package com.mantru.iotpot;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.mantru.iotpot.dao.DataDao;
import com.mantru.iotpot.dao.t_handing_config_nozzle;
import com.mantru.iotpot.dao.t_handing_config_box;
import com.mantru.iotpot.dao.t_public_config;
import com.mantru.iotpot.dao.t_public_config_bring;
import com.mantru.iotpot.dao.t_public_config_clean;
import com.mantru.iotpot.dao.t_public_config_clean_depth;
import com.mantru.iotpot.dao.t_public_config_clean_nozzle;
import com.mantru.iotpot.dao.t_public_config_feed_pot;
import com.mantru.iotpot.dao.t_vegetable_info;
import com.mantru.iotpot.dao.t_vegetable_info_steep;
import com.mantru.iotpot.dao.t_vegetable_info_steep_vegetable;
import com.mantru.iotpot.dao.t_vegetable_info_type;
import com.mantru.iotpot.eventbus.EventMessage;
import com.mantru.iotpot.job.CookingDetail;
import com.mantru.iotpot.job.CookingMaster;
import com.mantru.iotpot.job.CookingSteep;
import com.mantru.iotpot.job.HandingMaster;
import com.mantru.iotpot.job.JobMaster;
import com.mantru.iotpot.job.SteepCheckNode;
import com.mantru.iotpot.modbus.CRC16;
import com.mantru.iotpot.modbus.Common;
import com.mantru.iotpot.modbus.DownFileObject;
import com.mantru.iotpot.modbus.DownFileThread;
import com.mantru.iotpot.modbus.HttpThread;
import com.mantru.iotpot.modbus.ModbusRtuMaster;
import com.mantru.iotpot.modbus.OSUtil;
import com.mantru.iotpot.modbus.RobotClientEventThread;
import com.mantru.iotpot.modbus.WebUtil;

import com.mantru.iotpot.modbus.SaveLogThread;
import com.mantru.iotpot.modbus.Ymodem;
import com.tencent.bugly.crashreport.CrashReport;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONObject;


public class ApplicationClass extends Application
{
    //是否要跳过主板对接，true表示不需要自检
    public boolean is_test = false;
    //APP首页是不是已释放
    public boolean app_is_release = false;
    public String admin_password = "8888";
    //首页主窗口对象
    public Context main_context;
    //sqlite数据库对象
    public DataDao dao;
    //串口对象
    public ModbusRtuMaster com;
    //任务对象（旧的），没用了
    public JobMaster job;
    //任务对象（新的）
    public CookingMaster jobmaster;
    public HandingMaster handmaster;
    //推送信息的Socket长连接
    private RobotClientEventThread event;
    //H5本地路径
    public String web_local_url = Common.Local_H5_Url;
    //初始化网页、首页、故障页
    public String web_page_url_init = web_local_url +  "h5/index.html#/pages/dataSync/index";
    //public String web_page_url_init = web_local_url +  "test.html";
    public String web_page_url_index = web_local_url + "h5/index.html#/";
    public String web_page_url_error = web_local_url + "h5/index.html#/pages/error/index";
    //app类型、app版本等常量
    public final static String APP_Type = "pot";       //watch/pad/phone/pot分别代表手表、平板、手机、锅
    public String APP_Version = "V1.0.0";       //版本号，app升级也是读取这个值，自动和build.gradle里的versionName配置值一致
    //故障变量
    public String error_code = "", error_desc = "", error_data = "", error_type = "";
    public boolean error_is_show_ui = false;           //是否已弹出故障专用界面，true表示已弹

    public long time1 = 0, time2 = 0, time3 = 0;

    //系统全局变量
    public int net_work_status = 1;         //网络状态，1网络正常、0网络异常，主要由socket连接成功后判断网络状态，socket有断线5秒后重连的机制
    public int ui_status = 0;               //UI界面状态，0初始化、1首页、2炒菜中、3清洗中
    public long ui_status_begin_time = 0;   //UI界面状态的开始时间截，单位：ms
    public int init_data_progress = 0;      //ui_status=0初始化状态时的进度，0最小，100最大
    public long pot_read_temperature_last_time = 0;  //最后一次读取锅的红外温度的时间，单位：ms，要求每隔2秒读1次温度
    public long pot_read_error_last_time = 0;        //最后一次读取锅的故障码的时间，单位：ms，要求每隔1秒读取1次错误码
    public long pot_cooking_query_last_time = 0;     //最后一次轮询烹饪状态的时间，单位：ms，要求H5前端每隔1秒读1次状态
    public long pot_read_all_address_time = 0;       //最后一次读取全部地址的时间，单位：ms，要求每隔3秒读取1次全部地址
    public int  pot_temperature_value = 0;           //锅的红外温度值
    public boolean pot_temperature_is_error = false; //温度传感器是否故障，true是
    public String pot_read_param_password = "123456"; //设置系统参数的密码
    public long pot_read_param1_last_time = 0;       //最后一次读取电机参数的时间，单位：ms
    public String pot_read_param1_value = "";        //最后一次读取电机参数的值，json格式
    public String pot_read_param1_value_bak = "";    //最后一次读取电机参数的值，json格式
    public long pot_read_param2_last_time = 0;       //最后一次读取加热参数的时间，单位：ms
    public String pot_read_param2_value = "";        //最后一次读取加热参数的值，json格式
    public String pot_read_param2_value_bak = "";    //pot_read_param2_value变量的缓存
    public long pot_read_param3_last_time = 0;       //最后一次读取红外传感器参数的时间，单位：ms
    public String pot_read_param3_value = "";        //最后一次读取红外传感器参数的值，json格式
    public long pot_read_param4_last_time = 0;       //最后一次读取系统参数的时间，单位：ms
    public String pot_read_param4_value = "";        //最后一次读取系统器参数的值，json格式
    public String pot_read_param5_value = "";        //最后一次读取系统器参数的值，json格式
    public String pot_read_param4_value_bak = "";    //pot_read_param4_value变量的缓存
    public long pot_read_param4_value_0x0001 = 0;    //最后一次读取系统器参数的值，json格式
    public long page_index_last_time = 0;            //在首页最后一次刷新的时间

    //UI界面状态常量
    public final static int UI_STATUS_NeedLogin = -1; //未登录
    public final static int UI_STATUS_InitData = 0;   //初始化
    public final static int UI_STATUS_Index = 1;      //首页
    public final static int UI_STATUS_InFire = 2;     //炒菜中
    public final static int UI_STATUS_InClean = 3;    //清洗中

    //缓存里的变量
    public String activity_device_id = "";           //设备的SN
    public String activity_hardware_version = "";    //主板固件版本
    public String activity_software_version = "";    //主板软件版本，app端显示为系统版本号
    public String activity_ip_address = "";          //本地IP地址
    public String activity_network_type = "";        //网络类型，wifi、4G、以太网
    public String activity_device_name = "";         //型号名称
    public String activity_factory_name = "";        //制造厂商
    public String activity_company_name = "";        //店铺名称
    public String activity_oil_box_is_heat = "0";    //油灌加热，1是、0否
    public String activity_vegetable_order_by = "0"; //菜谱排序，1开开—>按照已经炒过的次数倒序、0关—>按照最后一次炒制的时间倒序
    public String activity_device_type = "炒菜机";         //机器类型
    public String activity_device_spec = "餐饮款";         //型号
    //APP版本号相关的变量
    public String app_version_new = "";          //APP新版本号
    public String app_version_down_url = "";     //P新版下载全路径
    public String app_version_memo = "";         //APP新版升级内容描述
    public String app_version_down_progress = "0";  //下载进度，从0到100

    //科大讯飞TTS的变量
    // 本地发音人列表
    private String[] localVoicersEntries;
    private String[] localVoicersValue;
    // 增强版发音人列表
    private String[] xttsVoicersEntries;
    private String[] xttsVoicersValue;

    private boolean is_need_put_param = false;   //true表示必须上传可修改的系统参数
    private List local_file_list;                //用线程下载的本地文件列表，结点是DownFileObject
    //锅位置设置与检测相关变量
    private int set_pot_position = -1;         //设置指令的锅位置（转义之后的）
    private int return_pot_position = -1;      //从串口读取回来的锅位置
    private long set_pot_position_time = 0;    //设置的时间截，单位：ms
    private long return_pot_position_time = 0; //读回来的时间截，单位：ms
    //锅实时的5个参数值
    private String realtime_pot_position = "2";  //锅位置：1洗锅位、2炒菜位、3出菜位
    public int realtime_fire_value = 0;          //档位，0-9档，值越大表示火力越大
    private String realtime_speed_value = "0";   //转速，0停、1慢、2中、3快
    private String realtime_rotation_value = "1";//锅转向，1逆时针、2顺时针
    private String realtime_is_show_gif = "0";   //是否显示gif动画，0不显示、1显示箭头往下gif、2显示箭头往上gif

    //锅位置：0未初始化、1倒水位、2倒菜位、3原位、0xF0运动过程中
    public int pot_position_value;
    public int pot_position_value_old;  //值为1or2or3时的旧值
    private long box_move_last_time;
    //投菜臂位置：0未初始化、1原位、2投菜位、0xF0运动过程中
    //料盒轨位置：0未初始化、1-4是盒子1-4位置、0xF0运动过程中
    public int box_position_value;
    //料盒投臂状态：0未初始化、1原位、2投菜位、0xF0运动过程中
    public int box_throw_move;
    public long box_throw_0xF0_time;
    private long box_throw_last_time;
    //机械臂和机械爪的设置相关的变量
    private boolean gripper_is_setting = false;
    private long gripper_setting_time = 0;
    private long gripper_throw_last_time;
    //机械爪转速，0-5档
    public int gripper_speed_value;
    public int gripper_speed_value_read;  //这个是读出来的
    //机械爪转向，0正方向、1反方向、2周期正反转
    public int gripper_rotation_value;
    //炒菜爪开关状态，0开关正常、1开关失效
    public int gripper_status_value;
    //机械臂位置，0未初始化、1放下、2抬起、0xF0运动过程中
    public int gripper_position_value;
    public int gripper_position_value_old;  //值为1or2时的旧值
    //机械爪寻位状态，0未初始化、1在原点、2运动过程中、3暂停中、0xF0寻位过程中
    public int gripper_position_status;
    //炒菜前要设置3个位置的变量
    private String setting3position_name = "";
    private long setting3position_time;
    private List<SteepCheckNode> setting3position_list;
    //炒菜中要投放第n个料盒
    private int setting_box_index;
    private int setting_box_release_type;
    private long setting_box_time;
    //IAP升级的变量
    public int iap_status = 0;    //IAP升级状态，0表示没有升级，1表示升级中，2表示已发送完文件等待重启
    private int iap_pack_count;   //总包数量
    private int iap_pack_index;   //当前已发送的包序号，从1开始
    private int iap_eot_count;    //EOT帧已发送数量
    private String iap_file_path; //bin文件的本地缓存全路径
    private byte[] iap_file_data; //bin文件读到byte[]数组里
    private int iap_file_crc_value;   //bin文件的CRC16值
    private boolean iap_is_wait_0x43; //是否在等待0x43回复，true是
    //料管清洗变量
    private String Cleaning_Nozzle_ID_List;
    private String Cleaning_Nozzle_Tishi_Last_Time;   //首页弹出提示料管清洗最后一次的时间，要求1天只弹1次
    private int[] Nozzle_Weigth_2_Time = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};  //10个喷泵喷100g的耗时，例如：32表示喷100克耗时3.2秒
    //下位机计算出来的时间变量
    private long address_0x001C_value;  //爪子原位检测最大时间
    private long address_0x001D_value;  //臂抬放时间
    private long address_0x001E_value;  //投菜模式1时间
    private long address_0x001F_value;  //投菜模式2时间
    private long address_0x0020_value;  //投菜模式3时间
    private long address_0x0021_value;  //投菜模式4时间
    private long address_0x0022_value;  //单料盒运动时间
    private long address_0x0023_value;  //料盒加减速时间

    //自用handle消息id
    private final static int MsgID_CheckSelfStatus = 104;      //读取自检状态
    private final static int MsgID_CheckDownFileFinish = 101;  //判断下载文件是否完成了
    private final static int MsgID_OnHttpGet = 105;            //完成一个http get异步
    private final static int MsgID_SocketData = 48;            //收到socket指令

    //2025.03.12  这是和UI界面共享的变量
    public int DeviceStatus = 0;      //界面状态，0代表需要进入初始化、1代表需要进入自检、2代表已完成自检并可以进入首页
    public int CheckSelfStatus = 0;   //自检状态，0代表未开始自检、1代表正在自检中、2代表已完成自检、3代表自检过程中发现故障、4代表自检过程中发生超时
    private long CheckSelfStatus_BeginTime = 0;   //自检开始时间，ms
    public long CheckSelfStatus_LastTime = 0;     //自检最后一次回复时间，ms
    public boolean IsLogin = false;   //是否已登录，true表示已登录，false表示未登录
    public String token = "";         //当前登录的token
    public String account = "";       //当前登录账号
    public String parent_company_id = "";  //集团公司id
    public String company_id = "";         //分店id
    public String user_type = "0";          //用户类型：2集团管理员、3门店管理员、4配网专员
    private long Upload43Data_LastTime = 0; //最后一次上报43个地址值的时间，ms
    private int MsgID_CheckSelf_Reset0_IsSend = 0;  //事件是否已发送了
    private int MsgID_CheckSelf_Reset1_IsSend = 0;  //事件是否已发送了
    private int MsgID_CheckSelf_Reset2_IsSend = 0;  //事件是否已发送了
    private int MsgID_CheckSelf_Reset3_IsSend = 0;  //事件是否已发送了
    private int MsgID_CheckSelf_Reset4_IsSend = 0;  //事件是否已发送了
    private int MsgID_CheckSelf_Reset5_IsSend = 0;  //事件是否已发送了

    @Override
    public void onCreate() {
        super.onCreate();
        try {
            CrashReport.initCrashReport(getApplicationContext(), "75f75e9adc", false);//腾讯Bugly
        }catch (Exception ex1){
            SaveLog("ApplicationClass.onCreate1出错：" + ex1.getMessage());
        }
        try {
            //创建sqlite对象
            dao = new DataDao(this);
            //创建串口对象
            com = new ModbusRtuMaster(this);
            //创建下载图片列表
            local_file_list = new ArrayList();
            //读取app版本名称，这里读的是build.gradle里的versionName
            try {
                APP_Version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
            } catch (Exception e1) {
            }
            //读取本地缓存
            token = WebUtil.GetCacheData(this, "user_token");
            account = WebUtil.GetCacheData(this, "user_account");
            user_type = WebUtil.GetCacheData(this, "user_type");
            company_id = WebUtil.GetCacheData(this, "user_company_id");
            parent_company_id = WebUtil.GetCacheData(this, "user_parent_company_id");
            activity_device_id = WebUtil.GetCacheData(this, "activity_device_id");
            activity_hardware_version = WebUtil.GetCacheData(this,"activity_hardware_version");
            activity_software_version = WebUtil.GetCacheData(this,"activity_software_version");
            activity_device_name = WebUtil.GetCacheData(this,"activity_device_name");
            activity_factory_name = WebUtil.GetCacheData(this,"activity_factory_name");
            activity_company_name = WebUtil.GetCacheData(this,"activity_company_name");
            activity_oil_box_is_heat = "0";  //WebUtil.GetCacheData(this,"activity_oil_box_is_heat");
            activity_vegetable_order_by = WebUtil.GetCacheData(this,"activity_vegetable_order_by");
            Cleaning_Nozzle_Tishi_Last_Time = WebUtil.GetCacheData(this,"Cleaning_Nozzle_Tishi_Last_Time");
            //读取本地ip、网络类型，第一次判断网络状态
            activity_ip_address = OSUtil.GetIPAddress(this);
            activity_network_type = OSUtil.GetNetworkType(this);
            if (activity_ip_address.length() >= 7 && activity_network_type.length() > 0)
                net_work_status = 1;
            else
                net_work_status = 0;
            if (company_id.length() == 0) company_id = "0";
            if (parent_company_id.length() == 0) parent_company_id = "0";
            if (activity_oil_box_is_heat.length() == 0) activity_oil_box_is_heat = "0";
            if (activity_vegetable_order_by.length() == 0) activity_vegetable_order_by = "0";
            if (Cleaning_Nozzle_Tishi_Last_Time.length() == 0) Cleaning_Nozzle_Tishi_Last_Time = "0";

            //判断用户是否已登录
            if (token.length() == 0) {
                IsLogin = false;
                DeviceStatus = -1;
                ui_status = UI_STATUS_NeedLogin;
                ui_status_begin_time = Common.GetTimeStamp13();
                if (activity_device_id.length() <= 5) {
                    if (is_test == true) {
                        //跳过读主板SN，用AndroidID代替
                        activity_device_id = OSUtil.Get_ANDROID_ID(this);
                        com.DeviceID = activity_device_id;
                        SocketAPI_Start();
                    } else {
                        //读取设备UID+软件版本号，从0x0064-0x006A，从低到高排
                        com.ReadHoldingRegister(0x01, 0x0064, 0x0007);
                    }
                }
                return;
            } else {
                IsLogin = true;
            }

            DeviceStatus = 1;     //进入自检
            CheckSelfStatus = 0;  //未开始自检
            com.DeviceID = activity_device_id;
            //启动socket长连接
            SocketAPI_Start();
            //油罐加热  app运行时不开加热
            //OilBoxIsHeat_SendCommand();
            //进入首页状态
            ui_status = UI_STATUS_Index;
            ui_status_begin_time = Common.GetTimeStamp13();

            //每天开机后就同步一次设备配置信息
            String api_url1 = "?txt_type=/potnew/init_data/&save_type=get_device_info&device_id=" + activity_device_id + "&app_version=" + APP_Version;
            HttpGet(api_url1, 0);
            //每天开机后就同步一次后台修改的参数
            String api_url2 = "?txt_type=/potnew/get_param/&save_type=get_param&device_id=" + activity_device_id;
            HttpGet(api_url2, 0);

        }catch (Exception ex2){
            SaveLog("ApplicationClass.onCreate2出错：" + ex2.getMessage());
        }
    }

    //终止事件
    @Override
    public void onTerminate() {
        super.onTerminate();
        System.out.println("------onTerminate啦");
    }

    //启动Socket长连接
    private void SocketAPI_Start()
    {
        try {
            if (event != null || activity_device_id.length() <= 0)
                return;
            event = new RobotClientEventThread(this, activity_device_id);
            event.SetHandle(handler);
            event.start();
        }catch (Exception ex){
        }
    }

    //设备开始初始化
    private void Device_InitData()
    {
        DeviceStatus = 0;
        ui_status = UI_STATUS_InitData;
        ui_status_begin_time = Common.GetTimeStamp13();
        init_data_progress = 0;
        String msg1 = "{\"progress\":"+init_data_progress+"}";
        EventMessage e1 = new EventMessage(EventMessage.MSG_ID_InitProgress, msg1);
        EventBus.getDefault().post(e1);
        //创建数据库
        dao.InitData();
        init_data_progress = 5;
        String msg2 = "{\"progress\":"+init_data_progress+"}";
        EventMessage e2 = new EventMessage(EventMessage.MSG_ID_InitProgress, msg2);
        EventBus.getDefault().post(e2);
        //读取设备全部调试参数，錅工说从0x0000读到0x006D
        //com.ReadHoldingRegister(0x01, 0x0000, 0x006D);
        //读取设备UID、软件版本，从0x0064-0x006A，从低到高排
        com.ReadHoldingRegister(0x01, 0x0064, 0x0007);
        return;
    }

    //打印日志
    public void Log(String value)
    {
        Common.Log(value);
    }

    //异步保存日志到云端
    public void SaveLog(String value)
    {
        System.out.println("-->" + value);
        SaveLogThread log_thread = new SaveLogThread(activity_device_id, value);
        log_thread.start();
    }

    //发送锅位设置指令
    //pot_position  锅位置：1洗锅位、2炒菜位、3出菜位、4回炒菜位、5停止倾倒、6恢复倾倒
    public void Device_SetPotPosition(String pot_position)
    {

    }


    /**
     * 串口收到的数据进行解码
     * @param data 收到的数据
     * @param read_address 读取的地址
     * @param read_len 读取数据长度
     */
    public void OnComData(String data, int read_address, int read_len)
    {
        try {
            //IAP升级
            if (iap_status == 1) {
                //IAP升级，第1个指令往0xFFFF地址写入0x5BB5，跟着下位机回复0xFF，还要等4秒回复0x43就可以开始发文件包了
                if (iap_is_wait_0x43 == true) {
                    if (data.equals("43")) {
                        iap_is_wait_0x43 = false;
                        IAP_Install_SendNextFrame();
                        return;
                    }
                    return;
                }

                IAP_Install_SendNextFrame();
                return;
            }
            //未登录
            if (ui_status == UI_STATUS_NeedLogin) {
                //读取设备UID、软件版本
                //data=01 03 0c 53 1c 00 59 c0 00 58 a4 94 22 07 25 95 37（读取回复数据长度=12，数据=531c0059c00058a494220725）
                if (read_address == 0x0064 && read_len == 0x0007) {
                    //设备UID占6字节，硬件版本占2字节，软件版本占2字节，一共14字节的数据
                    activity_device_id = data.substring(6, 30);
                    if (activity_device_id.equals("000000000000000000000000"))
                        activity_device_id = OSUtil.Get_ANDROID_ID(this);
                    com.DeviceID = activity_device_id;
                    //软件版本号占1字节，高8位是主版本号，低8位是次版本号，例如0x0102=V1.2
                    activity_software_version = "V" + Common.hex2int(data.substring(32, 34)) + "." + Common.hex2int(data.substring(30, 32));

                    SocketAPI_Start();
                    return;
                }
            }
            //初始化状态
            if (ui_status == UI_STATUS_InitData) {
                //读取设备全部调试参数
                //data=010380773594000bb800000000773594000bb800000000ffffffffffffffffffffffffffffffffffff00000000000000000000ffffffff000000000000000003e5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d149
                if (read_address == 0x001E && read_len == 0x0040) {
                }
                //读取设备UID、软件版本
                //data=01 03 0c 53 1c 00 59 c0 00 58 a4 94 22 07 25 95 37（读取回复数据长度=12，数据=531c0059c00058a494220725）
                if (read_address == 0x0064 && read_len == 0x0007) {
                    init_data_progress = 10;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    //设备UID占6字节，软件版本占1字节
                    activity_device_id = data.substring(6, 30);
                    if (activity_device_id.equals("000000000000000000000000"))
                        activity_device_id = OSUtil.Get_ANDROID_ID(this);
                    //软件版本号占1字节，高8位是主版本号，低8位是次版本号，例如0x0102=V1.2
                    activity_software_version = "V" + Common.hex2int(data.substring(32, 34)) + "." + Common.hex2int(data.substring(30, 32));
                    activity_ip_address = OSUtil.GetIPAddress(this);
                    activity_network_type = OSUtil.GetNetworkType(this);
                    com.DeviceID = activity_device_id;
                    SocketAPI_Start();
                    String api_url = "?txt_type=/potnew/init_data/&save_type=save_device_info&device_id=" + activity_device_id
                            + "&hardware_version=" + activity_hardware_version
                            + "&software_version=" + activity_software_version
                            + "&ip_address=" + activity_ip_address
                            + "&network_type=" + activity_network_type;
                    HttpGet(api_url, 0);
                    return;
                }


            }

            //读取自检状态0x003B
            if (read_address == 0x003B && read_len == 0x0001){
                String receive_data = data.replace(" ", "");
                String value_str1 = receive_data.substring(6, 8) + "00";
                String value_str2 = receive_data.substring(8, 10) + "00";
                long sub_value = Common.hex2int(value_str1);
                long sub_value2 = Common.hex2int(value_str2);

                Log("-->初始化状态值=" + sub_value + "," + sub_value2);
                //Bit15=1表示总自检完成
                if (sub_value >= 32768 || sub_value2 >= 32768) {
                    CheckSelfStatus = 2;    //完成自检
                    DeviceStatus = 2;       //可以进入首页
                    return;
                } else if ((sub_value & 32) > 0 || (sub_value & 64) > 0 || (sub_value & 128) > 0 || (sub_value & 256) > 0 || (sub_value & 512) > 0) {
                    CheckSelfStatus = 4;  //自检超时
                    SaveLog("下位机判断超时了-->" + sub_value);
                    EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Timeout, "");
                    EventBus.getDefault().post(e);
                    return;
                } else {
                    //判断自检超时120秒
                    long now = Common.GetTimeStamp13();
                    if (now - CheckSelfStatus_BeginTime >= 120000) {
                        CheckSelfStatus = 3;  //自检有故障
                        SaveLog("自检超时120秒了");
                        return;
                    }
                    CheckSelfStatus_LastTime = now + 500;
                    //500ms后读1次0x003B
                    Message msg1 = new Message();
                    msg1.what = MsgID_CheckSelfStatus;
                    handler.sendMessageDelayed(msg1, 500);
                    return;
                }
            }

            //读取全部地址的值
            if (read_address == 0x0000 && read_len == 0x6D) {
                String param_data = "", sub_param = "";
                long sub_value = 0;
                String receive_data = data.replace(" ", "");
                if (receive_data.length() != 446)
                    return;
                //上报全部寄存器的值
                String post_data = receive_data.substring(6);
                post_data = "post_data=" + URLEncoder.encode(post_data);
                String api_url = "?txt_type=/potnew/put_allvalue/&save_type=all&device_id=" + activity_device_id;
                //HttpPost(api_url, post_data, 0);

                //读软件版本号（也叫系统版本号）
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x006A, 2);
                String version_new = "V" + (sub_value / 256) + "." + (sub_value % 256);
                if (version_new.equals(activity_software_version) == false) {
                    activity_software_version = version_new;
                    WebUtil.SaveCacheData(this, "activity_software_version", activity_software_version);
                }
                //读8个下位机计算的时间变量
                address_0x001C_value = com.Decode_GetValue(receive_data, 0x0000, 0x001C, 2);
                address_0x001D_value = com.Decode_GetValue(receive_data, 0x0000, 0x001D, 2);
                address_0x001E_value = com.Decode_GetValue(receive_data, 0x0000, 0x001E, 2);
                address_0x001F_value = com.Decode_GetValue(receive_data, 0x0000, 0x001F, 2);
                address_0x0020_value = com.Decode_GetValue(receive_data, 0x0000, 0x0020, 2);
                address_0x0021_value = com.Decode_GetValue(receive_data, 0x0000, 0x0021, 2);
                address_0x0022_value = com.Decode_GetValue(receive_data, 0x0000, 0x0022, 2);
                address_0x0023_value = com.Decode_GetValue(receive_data, 0x0000, 0x0023, 2);

                //读10个喷泵的100g耗时值
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x004E, 2);
                Nozzle_Weigth_2_Time[0] = (int)(sub_value % 256);
                Nozzle_Weigth_2_Time[1] = (int)(sub_value / 256);
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x004F, 2);
                Nozzle_Weigth_2_Time[2] = (int)(sub_value % 256);
                Nozzle_Weigth_2_Time[3] = (int)(sub_value / 256);
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0050, 2);
                Nozzle_Weigth_2_Time[4] = (int)(sub_value % 256);
                Nozzle_Weigth_2_Time[5] = (int)(sub_value / 256);
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0051, 2);
                Nozzle_Weigth_2_Time[6] = (int)(sub_value % 256);
                Nozzle_Weigth_2_Time[7] = (int)(sub_value / 256);
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0052, 2);
                Nozzle_Weigth_2_Time[8] = (int)(sub_value % 256);
                Nozzle_Weigth_2_Time[9] = (int)(sub_value / 256);
                //机械爪速度，0-5档
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x003A, 2);
                this.gripper_speed_value_read = (int)sub_value;
                //火力档位，0-9档
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0054, 2);
                this.realtime_fire_value = (int)sub_value;
                //温度值，有小数的，280=28度，从-400至+400度
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x003F, 2);
                this.pot_temperature_value = (int)(sub_value / 10);
                this.pot_read_temperature_last_time = Common.GetTimeStamp13();
                //机械臂位置，0未初始化、1放下、2抬起、0xF0运动过程中
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0047, 2);
                gripper_position_value = (int)sub_value;
                //机械爪寻位状态，0未初始化、1在原点、2运动过程中、3暂停中、0xF0寻位过程中
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x003E, 2);
                gripper_position_status = (int)sub_value;

                //计算机械臂位置发生了变化就发EventBus
                if (gripper_position_value_old > 0 && gripper_position_value_old != gripper_position_value && (gripper_position_value == 1 || gripper_position_value == 2)) {
                    String msg = "{\"old_value\":"+gripper_position_value_old+",\"new_value\":"+gripper_position_value+"}";
                    SaveLog("MSG_ID_OnGripperChange-->" + msg);
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_OnGripperChange, msg);
                    EventBus.getDefault().post(e);
                }
                //计算机械臂处于运动中发EventBus
                if (gripper_position_value_old > 0 && gripper_position_value > 2) {
                    String msg = "{\"old_value\":"+gripper_position_value_old+",\"new_value\":"+(gripper_position_value_old==1?2:1)+"}";
                    SaveLog("MSG_ID_OnGripperMoving-->" + msg);
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_OnGripperMoving, msg);
                    EventBus.getDefault().post(e);
                }
                if (gripper_position_value == 1 || gripper_position_value == 2)
                    gripper_position_value_old = gripper_position_value;

                //对机械臂放下来之后才发爪子的转向+转速
                if (gripper_is_setting == true && gripper_position_value == 1) {
                    gripper_is_setting = false;
                    long now = Common.GetTimeStamp13();
                    if (now - gripper_setting_time <= 22000) {
                        //机械爪转向，0正方向、1反方向、2周期正反转
                        com.writeSingleRegister(0x01, 0x00E2, gripper_rotation_value, null);
                        //机械爪转速，0-5档
                        com.writeSingleRegister(0x01, 0x00E1, gripper_speed_value, null);
                    }
                }

                //2025.06.04 计算手动自检的复位
                //if (CheckSelfStatus >= 3) {
                    int ok_count = 0;
                    sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x003B, 2);
                    if ((sub_value & 1) > 0 && MsgID_CheckSelf_Reset0_IsSend == 0) {
                        ok_count++;
                        MsgID_CheckSelf_Reset0_IsSend = 1;
                        SaveLog("MsgID_CheckSelf_Reset0-->" + sub_value);
                        EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Reset0, "");
                        EventBus.getDefault().post(e);
                    }
                    if ((sub_value & 2) > 0 && MsgID_CheckSelf_Reset1_IsSend == 0) {
                        ok_count++;
                        MsgID_CheckSelf_Reset1_IsSend = 1;
                        SaveLog("MsgID_CheckSelf_Reset1-->" + sub_value);
                        EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Reset1, "");
                        EventBus.getDefault().post(e);
                    }
                    if ((sub_value & 4) > 0 && MsgID_CheckSelf_Reset2_IsSend == 0) {
                        ok_count++;
                        MsgID_CheckSelf_Reset2_IsSend = 1;
                        SaveLog("MsgID_CheckSelf_Reset2-->" + sub_value);
                        EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Reset2, "");
                        EventBus.getDefault().post(e);
                    }
                    if ((sub_value & 8) > 0 && MsgID_CheckSelf_Reset3_IsSend == 0) {
                        ok_count++;
                        MsgID_CheckSelf_Reset3_IsSend = 1;
                        SaveLog("MsgID_CheckSelf_Reset3-->" + sub_value);
                        EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Reset3, "");
                        EventBus.getDefault().post(e);
                    }
                    if ((sub_value & 16) > 0 && MsgID_CheckSelf_Reset4_IsSend == 0) {
                        ok_count++;
                        MsgID_CheckSelf_Reset4_IsSend = 1;
                        SaveLog("MsgID_CheckSelf_Reset4-->" + sub_value);
                        EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Reset4, "");
                        EventBus.getDefault().post(e);
                    }
                    if ((sub_value & 512) > 0 && MsgID_CheckSelf_Reset5_IsSend == 0) {
                        ok_count++;
                        MsgID_CheckSelf_Reset5_IsSend = 1;
                        SaveLog("MsgID_CheckSelf_Reset5-->" + sub_value);
                        EventMessage e = new EventMessage(EventMessage.MsgID_CheckSelf_Reset5, "");
                        EventBus.getDefault().post(e);
                    }
                    //if (ok_count >= 6)
                    //    CheckSelfStatus = 2;  //2自检成功
                //}

                //炒菜爪开关状态，0正常，1失效
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x003D, 2);
                gripper_status_value = (int)sub_value;
                if (gripper_status_value == 1) {
                    SaveLog("MSG_ID_ErrorGripper");
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_ErrorGripper, "");
                    EventBus.getDefault().post(e);
                }
                //锅口位置
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0048, 2);
                pot_position_value = (int)sub_value;
                //计算锅口位置发生了变化就发EventBus
                if (pot_position_value_old > 0 && pot_position_value_old != pot_position_value && (pot_position_value == 1 || pot_position_value == 2 || pot_position_value == 3)) {
                    String msg = "{\"old_value\":"+pot_position_value_old+",\"new_value\":"+pot_position_value+"}";
                    SaveLog("MSG_ID_OnPotChange-->" + msg);
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_OnPotChange, msg);
                    EventBus.getDefault().post(e);
                }
                //计算锅口处于运动中发EventBus
                if (pot_position_value_old > 0 && pot_position_value > 3) {
                    String msg = "{\"old_value\":"+pot_position_value_old+"}";
                    SaveLog("MSG_ID_OnPotMoving-->" + msg);
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_OnPotMoving, msg);
                    EventBus.getDefault().post(e);
                }
                if (pot_position_value == 1 || pot_position_value == 2 || pot_position_value == 3)
                    pot_position_value_old = pot_position_value;

                //料盒投臂状态
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0049, 2);
                box_throw_move = (int)sub_value;
                //料盒轨位置：0未初始化、1-4是盒子1-4位置、0xF0运动过程中
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x004A, 2);
                box_position_value = (int)sub_value;

                System.out.println("---->锅口=" + pot_position_value + "，料盒=" + box_position_value + "，机械臂=" + gripper_position_value);

                //料盒投放臂在运动中的计算
                if (box_throw_move >= 2) {
                    box_throw_0xF0_time = Common.GetTimeStamp13();
                }
                //料盒1投完之后要自动移动到料盒2
                if (box_position_value <= 3 && box_throw_move == 1) {
                    long now = Common.GetTimeStamp13();
                    if (now - box_throw_0xF0_time <= 5000) {
                        box_throw_0xF0_time = 0;
                        //料盒移动到下一个位
                        Cooking_SettingBoxPosition(box_position_value + 1, 0x00);
                    }
                }
                //判断炒菜前的3个到位状态
                if (gripper_position_value == 1 && pot_position_value == 3 && box_position_value == 1) {
                    if (setting3position_name.equals("jobmaster") && jobmaster != null && jobmaster.steep_status == 0) {
                        setting3position_name = "";
                        jobmaster.Start();
                    }
                    if (setting3position_name.equals("handmaster") && handmaster != null && handmaster.steep_status == 0) {
                        setting3position_name = "";
                        handmaster.Start();
                    }
                }
                //开始炒菜时要按先后顺序：锅回原位、机械臂放下、料盒轨回到第1位
                if (setting3position_name.equals("jobmaster") || setting3position_name.equals("handmaster")) {
                    if (setting3position_list != null && setting3position_list.size() > 0) {
                        SteepCheckNode node = setting3position_list.get(0);
                        //检测锅
                        if (node.check_name.equals("pot_position_value") && pot_position_value == node.check_value) {
                            setting3position_list.remove(0);
                            if (setting3position_list.size() > 0)
                                node = setting3position_list.get(0);
                            else
                                node = null;
                        }
                        //检测机械臂
                        if (node.check_name.equals("gripper_position_value") && gripper_position_value == node.check_value) {
                            setting3position_list.remove(0);
                            if (setting3position_list.size() > 0)
                                node = setting3position_list.get(0);
                            else
                                node = null;
                        }
                        //检测料盒位置
                        if (node.check_name.equals("box_position_value") && box_position_value == node.check_value) {
                            setting3position_list.remove(0);
                            if (setting3position_list.size() > 0)
                                node = setting3position_list.get(0);
                            else
                                node = null;
                        }
                        //发指令
                        if (node != null && node.is_send == false) {
                            node.is_send = true;
                            com.writeSingleRegister(0x01, node.command_address, node.command_value, null);
                        }
                    }
                }
                //判断炒菜中的料盒轨移动到位了就投菜
                if (setting_box_index > 0 && box_position_value == setting_box_index && setting_box_release_type > 0){
                    setting_box_index = 0;
                    //投菜
                    com.writeSingleRegister(0x01, 0x00DD, setting_box_release_type, null);
                    setting_box_release_type = 0;
                }

                //读故障码
                boolean is_has_error = false;
                //0x0027  自检报错，黎工说进入首页之后就不要再弹这个自检超时的故障了
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0027, 2);
                if (sub_value > 0 && DeviceStatus != 2) {
                    is_has_error = true;
                    String error_code2 = "" + sub_value;
                    String error_desc2 = "";
                    String error_type2 = "自检报错";
                    if (sub_value == 1) { error_code2 = "ES1"; error_desc2 = "锅自检过程超时"; }
                    if (sub_value == 2) { error_code2 = "ES2"; error_desc2 = "导轨自检过程超时"; }
                    if (sub_value == 3) { error_code2 = "ES3"; error_desc2 = "机械臂自检过程超时"; }
                    if (sub_value == 4) { error_code2 = "ES4"; error_desc2 = "投菜自检过程超时"; }
                    if (sub_value == 5) { error_code2 = "ES5"; error_desc2 = "炒菜自检过程超时"; }
                    //相同的故障只报1次
                    if (error_code2.equals(error_code) == false) {
                        dao.SaveErrorCode(error_code, error_code2, error_type2, error_desc2, error_code2);
                        PutError(error_code2, error_type2, error_desc2);
                        error_type = error_type2;
                        error_code = error_code2;
                        error_desc = error_desc2;
                        String msg = "{\"error_code\":\"" + error_code2 + "\",\"error_desc\":\"" + error_desc2 + "\",\"error_type\":\"自检报错\"}";
                        SaveLog("MSG_ID_ErrorInfo-->" + msg);
                        EventMessage e = new EventMessage(EventMessage.MSG_ID_ErrorInfo, msg);
                        EventBus.getDefault().post(e);
                    }
                }
                //0x0043  热电偶报错状态，改名为：传感器故障
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x0043, 2);
                if (sub_value >= 32768) {
                    is_has_error = true;
                    pot_temperature_is_error = true;
                    String error_code2 = com.Decode_GetValue_Hex(receive_data, 0x0000, 0x0043, 2).toUpperCase();
                    String error_desc2 = "传感器故障";
                    String error_type2 = "传感器故障";
                    //相同的故障只报1次
                    if (error_code2.equals(error_code) == false) {
                        dao.SaveErrorCode(error_code, error_code2, error_type2, error_desc2, error_code2);
                        PutError(error_code2, error_type2, error_desc2);
                        error_type = error_type2;
                        error_code = error_code2;
                        error_desc = error_desc2;
                        String msg = "{\"error_code\":\"" + error_code2 + "\",\"error_desc\":\"" + error_desc2 + "\",\"error_type\":\"传感器故障\"}";
                        SaveLog("MSG_ID_ErrorInfo-->" + msg);
                        //EventMessage e = new EventMessage(EventMessage.MSG_ID_ErrorInfo, msg);
                        //EventBus.getDefault().post(e);
                    }
                } else {
                    pot_temperature_is_error = false;
                }
                //0x005F  机芯故障
                sub_value = com.Decode_GetValue(receive_data, 0x0000, 0x005F, 2);
                if (sub_value > 0) {
                    is_has_error = true;
                    String error_code2 = com.Decode_GetValue_Hex(receive_data, 0x0000, 0x005F, 2).toUpperCase();
                    String error_desc2 = com.Decode_ErrorCode(error_code2);
                    String error_type2 = "机芯故障";
                    if (error_code2.startsWith("00")) error_code2 = "E" + error_code2.substring(2);
                    //相同的故障只报1次
                    if (error_code2.equals(error_code) == false) {
                        dao.SaveErrorCode(error_code, error_code2, error_type2, error_desc2, error_code2);
                        PutError(error_code2, error_type2, error_desc2);
                        error_type = error_type2;
                        error_code = error_code2;
                        error_desc = error_desc2;
                        String msg = "{\"error_code\":\"" + error_code2 + "\",\"error_desc\":\"" + error_desc2 + "\",\"error_type\":\"机芯故障\"}";
                        SaveLog("MSG_ID_ErrorInfo-->" + msg);
                        EventMessage e = new EventMessage(EventMessage.MSG_ID_ErrorInfo, msg);
                        EventBus.getDefault().post(e);
                    }
                }
                if (is_has_error == false) {
                    error_code = "";
                    error_desc = "";
                    error_type = "";
                }

                //解读43个地址的值并上报到云端，每3秒上报1次
                long now = Common.GetTimeStamp13();
                if (now - Upload43Data_LastTime >= 3000) {
                    Upload43Data_LastTime = now;
                    for (int i = 0; i < Common.upload_address_int.length; i++) {
                        if (Common.upload_address_int[i] == 0x0059) {
                            sub_value = com.Decode_GetValue(receive_data, 0x0000, Common.upload_address_int[i], 4);
                            sub_param = "{\"n\":\"" + Common.upload_address_str1[i] + "\",\"t\":\"" + Common.upload_address_str2[i] + "\",\"v\":\"" + sub_value + "\"}";
                        } else if (Common.upload_address_int[i] == 0x0064) {
                            String hex_value = com.Decode_GetValue_Hex(receive_data, 0x0000, Common.upload_address_int[i], 12).toUpperCase();
                            sub_param = "{\"n\":\"" + Common.upload_address_str1[i] + "\",\"t\":\"" + Common.upload_address_str2[i] + "\",\"v\":\"" + hex_value + "\"}";
                        } else {
                            sub_value = com.Decode_GetValue(receive_data, 0x0000, Common.upload_address_int[i], 2);
                            sub_param = "{\"n\":\"" + Common.upload_address_str1[i] + "\",\"t\":\"" + Common.upload_address_str2[i] + "\",\"v\":\"" + sub_value + "\"}";
                        }
                        if (i > 0)
                            param_data += ",";
                        param_data += sub_param;
                    }
                    if (param_data.length() > 0) {
                        post_data = "{\"param_data\":[" + param_data + "]}";
                        post_data = "post_data=" + URLEncoder.encode(post_data);
                        api_url = "?txt_type=/potnew/put_param/&save_type=all&device_id=" + activity_device_id;
                        HttpPost(api_url, post_data, 0);
                    }
                }


            }


        }catch (Exception ex1){
            SaveLog("ApplicationClass.OnComData出错：data=" + data + ",error=" + ex1.getMessage());
        }
    }

    /**
     * HTTP异步收到的数据进行处理
     * @param json_data 收到的数据
     */
    public void OnHttpData(String json_data, String save_type)
    {
        try {
            Log("OnHttpData-->" + json_data);
            //保存本地菜谱致云端后返回云端的菜谱id
            if (save_type.equals("sendvegetabletoserver")) {
                String device_vegetable_id = Common.JSON_GetFieldValue(json_data, "device_vegetable_id");
                String server_vegetable_id = Common.JSON_GetFieldValue(json_data, "server_vegetable_id");
                if (device_vegetable_id.length() > 0 && server_vegetable_id.length() > 0) {
                    t_vegetable_info tb = new t_vegetable_info();
                    tb.vegetable_id = device_vegetable_id;
                    tb.server_vegetable_id = server_vegetable_id;
                    tb.is_need_sendtoserver = "0";
                    dao.ExecSQL(tb.update_save2server_sql, tb.GetUpdateSend2ServerValues());
                }
                return;
            }

            //后台修改了设备参数
            if (save_type.equals("get_param")) {
                //后台是否存在该设备参数，is_exists=0表示设备端必须上传全部可修改的参数值
                String is_exists = Common.JSON_GetFieldValue(json_data, "is_exists");
                if (is_exists.equals("0")) {
                    is_need_put_param = true;
                    com.ReadHoldingRegister(0x01, 0x0000, 0x6D);
                }
                if (is_exists.equals("1")) {
                    int param_count = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "param_count"));
                    if (param_count <= 0) {
                        is_need_put_param = false;
                        com.ReadHoldingRegister(0x01, 0x0000, 0x6D);
                    } else {
                        try {
                            int steep_count = 1;
                            JobMaster job = new JobMaster(this, "set_param", steep_count);
                            int steep_index = 1;
                            //总时长，将time_value转换为秒的值，单位：秒
                            int time_long = 1 * param_count;
                            job.time_long += time_long;

                            JSONObject json_object = new JSONObject(json_data);
                            JSONArray json_array = json_object.getJSONArray("param_data");
                            for (int i = 0; i < json_array.length(); i++) {
                                JSONObject sub_json_object = json_array.getJSONObject(i);
                                String name = sub_json_object.getString("param_name").replace("0x", "");
                                String value = sub_json_object.getString("param_value");
                                //写入寄存器的值
                                int start_address = Integer.parseInt(name, 16);
                                int output_value = Integer.parseInt(value);
                                job.AddJobNode(JobMaster.JOB_NODE_TYPE_USER, steep_index, 0x01, 0x06, start_address, 0x01, output_value, false, 0);
                                //写入保存位的值0x5A
                                if (start_address >= 0x0047 && start_address <= 0x004A)
                                    job.AddJobNode(JobMaster.JOB_NODE_TYPE_USER, steep_index, 0x01, 0x06, 0x0022, 0x01, 0x5A, false, 0);
                                if (start_address >= 0x004B && start_address <= 0x004C)
                                    job.AddJobNode(JobMaster.JOB_NODE_TYPE_USER, steep_index, 0x01, 0x06, 0x0027, 0x01, 0x5A, false, 0);
                                if (start_address >= 0x005A && start_address <= 0x0064)
                                    job.AddJobNode(JobMaster.JOB_NODE_TYPE_USER, steep_index, 0x01, 0x06, 0x0046, 0x01, 0x5A, false, 0);
                                if (start_address >= 0x0051 && start_address <= 0x0059)
                                    job.AddJobNode(JobMaster.JOB_NODE_TYPE_USER, steep_index, 0x01, 0x06, 0x0046, 0x01, 0x5A, false, 0);
                            }
                            //时长的缩写格式，格式mm:ss
                            String time_value = "00:01";
                            job.AddSteep(1, steep_index, 0, 0, time_value, time_long, 0, 0, 0, "");
                            job = job;
                            job.Start();
                        } catch (Exception ex) {
                            SaveLog("ActivityMain.MainForm_OnHttpData出错,save_type=get_param,json_data=" + json_data + ",错误内容：" + ex.getMessage());
                        }
                    }
                }
                return;
            }
            //检查app是否有新版本
            if (save_type.equals("check_app_upgrade")) {
                if (json_data.contains("app_version")) {
                    app_version_new = Common.JSON_GetFieldValue(json_data, "app_version");
                    app_version_down_url = Common.JSON_GetFieldValue(json_data, "down_url");
                    app_version_memo = Common.JSON_GetFieldValue(json_data, "memo");
                }
            }
            //获取设备参数回复
            if (save_type.equals("get_device_info")) {
                activity_device_name = Common.JSON_GetFieldValue(json_data, "device_name");   //型号名称
                activity_factory_name = Common.JSON_GetFieldValue(json_data, "factory_name"); //制造厂商
                activity_company_name = Common.JSON_GetFieldValue(json_data, "company_name"); //店铺名称
                WebUtil.SaveCacheData(this, "activity_device_name", activity_device_name);
                WebUtil.SaveCacheData(this, "activity_factory_name", activity_factory_name);
                WebUtil.SaveCacheData(this, "activity_company_name", activity_company_name);
                //判断是否有新版本
                if (json_data.contains("app_version")) {
                    app_version_new = Common.JSON_GetFieldValue(json_data, "app_version");
                    app_version_down_url = Common.JSON_GetFieldValue(json_data, "down_url");
                    app_version_memo = Common.JSON_GetFieldValue(json_data, "memo");
                }
                //2023.08.23 要求开机的时候同步一下TTS的设置
                if (ui_status == UI_STATUS_Index) {
                    //通用配置
                    String public_data = Common.JSON_GetFieldValue(json_data, "config_data");
                    t_public_config ent = new t_public_config();
                    ent.config_id = "1";
                    ent.tts_param_001 = Common.JSON_GetFieldValue(public_data, "tts_param_001");
                    ent.tts_param_002 = Common.JSON_GetFieldValue(public_data, "tts_param_002");
                    ent.tts_param_003 = Common.JSON_GetFieldValue(public_data, "tts_param_003");
                    ent.tts_param_004 = Common.JSON_GetFieldValue(public_data, "tts_param_004");
                    ent.tts_param_005 = Common.JSON_GetFieldValue(public_data, "tts_param_005");
                    ent.tts_param_006 = Common.JSON_GetFieldValue(public_data, "tts_param_006");
                    ent.device_param_006 = Common.JSON_GetFieldValue(public_data, "device_param_006");
                    ent.update_time = String.valueOf(Common.GetTimeStamp10());
                    dao.ExecSQL(ent.update_sql, ent.GetUpdateValues());
                    //TTS_Init();
                }
                //2023.09.04 改：每天开机后就不用启用偷偷同步系统菜谱
                if (ui_status != UI_STATUS_Index) {
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_vegetable_info&device_id=" + activity_device_id + "&start=1&limit=10";
                    HttpGet(api_url, 0);
                }
                return;
            }
            //保存设备参数回复
            if (save_type.equals("save_device_info")) {
                activity_device_name = Common.JSON_GetFieldValue(json_data, "device_name");   //型号名称
                activity_factory_name = Common.JSON_GetFieldValue(json_data, "factory_name"); //制造厂商
                activity_company_name = Common.JSON_GetFieldValue(json_data, "company_name"); //店铺名称
                WebUtil.SaveCacheData(this, "activity_device_name", activity_device_name);
                WebUtil.SaveCacheData(this, "activity_factory_name", activity_factory_name);
                WebUtil.SaveCacheData(this, "activity_company_name", activity_company_name);
                String api_url = "?txt_type=/potnew/init_data/&save_type=t_public_config&device_id=" + activity_device_id;
                HttpGet(api_url, 0);
                return;
            }
            //通用配置表
            if (save_type.equals("t_public_config")) {
                String device_data = Common.JSON_GetFieldValue(json_data, "device_data");
                //型号名称
                String activity_model_name = Common.JSON_GetFieldValue(device_data, "model_name");
                //制造厂商
                String activity_factory_name = Common.JSON_GetFieldValue(device_data, "factory_name");
                //店铺名称
                String activity_company_name = Common.JSON_GetFieldValue(device_data, "company_name");
                //设备状态，1启用、0禁用
                String activity_device_status = Common.JSON_GetFieldValue(device_data, "status");
                //维保结束日期，格式YYYY-MM-DD
                String activity_maintain_end_time = Common.JSON_GetFieldValue(device_data, "maintain_end_time");
                WebUtil.SaveCacheData(this, "activity_model_name", activity_model_name);
                WebUtil.SaveCacheData(this, "activity_factory_name", activity_factory_name);
                WebUtil.SaveCacheData(this, "activity_company_name", activity_company_name);
                WebUtil.SaveCacheData(this, "activity_device_status", activity_device_status);
                WebUtil.SaveCacheData(this, "activity_maintain_end_time", activity_maintain_end_time);
                //通用配置
                String public_data = Common.JSON_GetFieldValue(json_data, "public_data");
                t_public_config ent = new t_public_config();
                ent.config_id = "1";
                ent.device_param_001 = Common.JSON_GetFieldValue(public_data, "device_param_001");
                ent.device_param_002 = Common.JSON_GetFieldValue(public_data, "device_param_002");
                ent.device_param_003 = Common.JSON_GetFieldValue(public_data, "device_param_003");
                ent.device_param_004 = Common.JSON_GetFieldValue(public_data, "device_param_004");
                ent.device_param_005 = Common.JSON_GetFieldValue(public_data, "device_param_005");
                ent.device_param_006 = Common.JSON_GetFieldValue(public_data, "device_param_006");
                ent.device_param_007 = Common.JSON_GetFieldValue(public_data, "device_param_007");
                ent.device_param_008 = Common.JSON_GetFieldValue(public_data, "device_param_008");
                ent.device_param_009 = Common.JSON_GetFieldValue(public_data, "device_param_009");
                ent.device_param_010 = Common.JSON_GetFieldValue(public_data, "device_param_010");
                ent.device_param_011 = Common.JSON_GetFieldValue(public_data, "device_param_011");
                ent.tts_param_001 = Common.JSON_GetFieldValue(public_data, "tts_param_001");
                ent.tts_param_002 = Common.JSON_GetFieldValue(public_data, "tts_param_002");
                ent.tts_param_003 = Common.JSON_GetFieldValue(public_data, "tts_param_003");
                ent.tts_param_004 = Common.JSON_GetFieldValue(public_data, "tts_param_004");
                ent.tts_param_005 = Common.JSON_GetFieldValue(public_data, "tts_param_005");
                ent.tts_param_006 = Common.JSON_GetFieldValue(public_data, "tts_param_006");
                ent.update_time = String.valueOf(Common.GetTimeStamp10());
                dao.ExecSQL(ent.delete_sql, ent.GetDeleteValues());
                dao.Insert(ent.table_name, ent.GetInsertContentValues());
                //初始化状态才计算进度和自动下载
                if (ui_status == UI_STATUS_InitData) {
                    init_data_progress = 13;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_public_config_clean&device_id=" + activity_device_id + "&company_id=" + company_id + "&parent_company_id=" + parent_company_id ;
                    HttpGet(api_url, 0);
                }
                return;
            }
            //简单清洗配置表
            if (save_type.equals("t_public_config_clean")) {
                try {
                    JSONObject json_obj = new JSONObject(json_data);
                    //洗锅表
                    t_public_config_clean ent = new t_public_config_clean();
                    ent.clean_id = "1";
                    ent.clean1_data = json_obj.getJSONArray("data").getJSONObject(0).getJSONArray("clean1_data").toString();
                    ent.clean2_data = json_obj.getJSONArray("data").getJSONObject(0).getJSONArray("clean2_data").toString();
                    ent.clean3_data = json_obj.getJSONArray("data").getJSONObject(0).getJSONArray("clean3_data").toString();
                    ent.clean4_data = json_obj.getJSONArray("data").getJSONObject(0).getJSONArray("clean4_data").toString();
                    dao.Insert(ent.table_name, ent.GetInsertContentValues());
                    //养锅表
                    t_public_config_bring ent3 = new t_public_config_bring();
                    ent3.clean_id = "1";
                    ent3.clean1_data = json_obj.getJSONArray("bring_data").getJSONObject(0).getJSONArray("clean1_data").toString();
                    ent3.clean2_data = json_obj.getJSONArray("bring_data").getJSONObject(0).getJSONArray("clean2_data").toString();
                    ent3.clean3_data = json_obj.getJSONArray("bring_data").getJSONObject(0).getJSONArray("clean3_data").toString();
                    ent3.clean4_data = json_obj.getJSONArray("bring_data").getJSONObject(0).getJSONArray("clean4_data").toString();
                    dao.Insert(ent3.table_name, ent3.GetInsertContentValues());
                    //料管清洗配置表
                    t_public_config_clean_nozzle ent2 = new t_public_config_clean_nozzle();
                    long time = Common.GetTimeStamp10(Common.GetDataTimeString().substring(0, 10).trim() + " 00:00:00");
                    ent2.clean_id = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("clean_id").toString();
                    ent2.remind_begin_time = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("remind_begin_time").toString();
                    ent2.remind_end_time = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("remind_end_time").toString();
                    ent2.is_nozzle1 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle1").toString();
                    ent2.is_nozzle2 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle2").toString();
                    ent2.is_nozzle3 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle3").toString();
                    ent2.is_nozzle4 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle4").toString();
                    ent2.is_nozzle5 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle5").toString();
                    ent2.is_nozzle6 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle6").toString();
                    ent2.is_nozzle7 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle7").toString();
                    ent2.is_nozzle8 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle8").toString();
                    ent2.is_nozzle9 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle9").toString();
                    ent2.is_nozzle10 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle10").toString();
                    ent2.is_nozzle11 = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("is_nozzle11").toString();
                    ent2.nozzle1_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle1_value").toString();
                    ent2.nozzle2_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle2_value").toString();
                    ent2.nozzle3_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle3_value").toString();
                    ent2.nozzle4_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle4_value").toString();
                    ent2.nozzle5_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle5_value").toString();
                    ent2.nozzle6_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle6_value").toString();
                    ent2.nozzle7_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle7_value").toString();
                    ent2.nozzle8_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle8_value").toString();
                    ent2.nozzle9_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle9_value").toString();
                    ent2.nozzle10_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle10_value").toString();
                    ent2.nozzle11_value = json_obj.getJSONArray("nozzle_data").getJSONObject(0).getString("nozzle11_value").toString();
                    ent2.nozzle1_time = "" + time;
                    ent2.nozzle2_time = "" + time;
                    ent2.nozzle3_time = "" + time;
                    ent2.nozzle4_time = "" + time;
                    ent2.nozzle5_time = "" + time;
                    ent2.nozzle6_time = "" + time;
                    ent2.nozzle7_time = "" + time;
                    ent2.nozzle8_time = "" + time;
                    ent2.nozzle9_time = "" + time;
                    ent2.nozzle10_time = "" + time;
                    ent2.nozzle11_time = "" + time;
                    dao.Insert(ent2.table_name, ent2.GetInsertContentValues());
                } catch (Exception ex22){
                    SaveLog("插入t_public_config_clean表出错：" + ex22.getMessage());
                }

                //初始化状态才计算进度和自动下载
                if (ui_status == UI_STATUS_InitData) {
                    init_data_progress = 17;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_public_config_clean_depth&device_id=" + activity_device_id;
                    HttpGet(api_url, 0);
                }
                return;
            }
            //深度清洗配置表
            if (save_type.equals("t_public_config_clean_depth")) {
                int clean_count = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "clean_count"));
                String clean_data = Common.JSON_GetFieldValue(json_data, "clean_data");
                for (int i = 1; i <= clean_count; i++) {
                    String sub_json_data = Common.JSON_GetRecordData(json_data, i);
                    if (sub_json_data.length() > 10) {
                        t_public_config_clean_depth ent = new t_public_config_clean_depth();
                        ent.clean_id = Common.JSON_GetFieldValue(sub_json_data, "clean_id");
                        ent.steep_index = Common.JSON_GetFieldValue(sub_json_data, "steep_index");
                        ent.pot_position = Common.JSON_GetFieldValue(sub_json_data, "pot_position");
                        ent.fire_value = Common.JSON_GetFieldValue(sub_json_data, "fire_value");
                        ent.time_value = Common.JSON_GetFieldValue(sub_json_data, "time_value");
                        ent.time_long = Common.JSON_GetFieldValue(sub_json_data, "time_long");
                        ent.speed_value = Common.JSON_GetFieldValue(sub_json_data, "speed_value");
                        ent.rotation_value = Common.JSON_GetFieldValue(sub_json_data, "rotation_value");
                        ent.status = Common.JSON_GetFieldValue(sub_json_data, "status");
                        ent.tts_text = Common.JSON_GetFieldValue(sub_json_data, "tts_text");
                        ent.update_time = String.valueOf(Common.GetTimeStamp10());
                        dao.Insert(ent.table_name, ent.GetInsertContentValues());
                    }
                }
                //初始化状态才计算进度和自动下载
                if (ui_status == UI_STATUS_InitData) {
                    init_data_progress = 18;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_public_config_feed_pot";
                    HttpGet(api_url, 0);
                }
                return;
            }
            //一键养锅配置表
            if (save_type.equals("t_public_config_feed_pot")) {
                int clean_count = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "clean_count"));
                String clean_data = Common.JSON_GetFieldValue(json_data, "clean_data");
                for (int i = 1; i <= clean_count; i++) {
                    String sub_json_data = Common.JSON_GetRecordData(json_data, i);
                    if (sub_json_data.length() > 10) {
                        t_public_config_feed_pot ent = new t_public_config_feed_pot();
                        ent.clean_id = Common.JSON_GetFieldValue(sub_json_data, "clean_id");
                        ent.steep_index = Common.JSON_GetFieldValue(sub_json_data, "steep_index");
                        ent.pot_position = Common.JSON_GetFieldValue(sub_json_data, "pot_position");
                        ent.fire_value = Common.JSON_GetFieldValue(sub_json_data, "fire_value");
                        ent.time_value = Common.JSON_GetFieldValue(sub_json_data, "time_value");
                        ent.time_long = Common.JSON_GetFieldValue(sub_json_data, "time_long");
                        ent.speed_value = Common.JSON_GetFieldValue(sub_json_data, "speed_value");
                        ent.rotation_value = Common.JSON_GetFieldValue(sub_json_data, "rotation_value");
                        ent.status = Common.JSON_GetFieldValue(sub_json_data, "status");
                        ent.tts_text = Common.JSON_GetFieldValue(sub_json_data, "tts_text");
                        ent.update_time = String.valueOf(Common.GetTimeStamp10());
                        dao.Insert(ent.table_name, ent.GetInsertContentValues());
                    }
                }
                //初始化状态才计算进度和自动下载
                if (ui_status == UI_STATUS_InitData) {
                    init_data_progress = 20;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_vegetable_info_type";
                    HttpGet(api_url, 0);
                }
                return;
            }
            //保存菜谱分类表
            if (save_type.equals("t_vegetable_info_type")) {
                int item_count = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "item_count"));
                String item_data = Common.JSON_GetFieldValue(json_data, "item_data");
                for (int i = 1; i <= item_count; i++) {
                    String sub_json_data = Common.JSON_GetRecordData(json_data, i);
                    if (sub_json_data.length() > 10) {
                        t_vegetable_info_type ent = new t_vegetable_info_type();
                        ent.type_id = Common.JSON_GetFieldValue(sub_json_data, "type_id");
                        ent.parent_type_id = Common.JSON_GetFieldValue(sub_json_data, "parent_type_id");
                        ent.type_name = Common.JSON_GetFieldValue(sub_json_data, "type_name");
                        ent.status = Common.JSON_GetFieldValue(sub_json_data, "status");
                        ent.sort_index = Common.JSON_GetFieldValue(sub_json_data, "sort_index");
                        dao.Insert(ent.table_name, ent.GetInsertContentValues());
                    }
                }
                //初始化状态才计算进度和自动下载
                if (ui_status == UI_STATUS_InitData) {
                    init_data_progress = 30;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_vegetable_info&start=1&limit=10";
                    HttpGet(api_url, 0);
                }
                return;
            }
            //菜谱管理表
            if (save_type.equals("t_vegetable_info")) {
                int page_index = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "page_index"));
                int page_count = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "page_count"));
                int data_size = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "data_size"));
                int progress_value = 70 / page_count / data_size;
                try {
                    JSONObject json_object = new JSONObject(json_data);
                    JSONArray json_array = json_object.getJSONArray("data");
                    for (int i = 0; i < json_array.length(); i++) {
                        //主表
                        JSONObject sub_json_object = json_array.getJSONObject(i);
                        t_vegetable_info ent = new t_vegetable_info();
                        ent.vegetable_id = sub_json_object.getString("vegetable_id");
                        ent.server_vegetable_id = ent.vegetable_id;
                        ent.is_need_sendtoserver = "0";
                        if (dao.IsExists(ent.entity_sql, ent.GetEntityValues()) == false) {
                            ent.company_id = sub_json_object.getString("company_id");
                            ent.parent_company_id = sub_json_object.getString("parent_company_id");
                            ent.vegetable_name = sub_json_object.getString("vegetable_name");
                            ent.work_time = sub_json_object.getString("work_time");
                            ent.sort_index = sub_json_object.getString("sort_index");
                            ent.push_src = sub_json_object.getString("push_src");
                            ent.face_image_url = sub_json_object.getString("face_image_url");
                            ent.spec_data = sub_json_object.getJSONArray("spec_data").toString();
                            ent.firsh_char = sub_json_object.getString("firsh_char").toString();
                            ent.from_vegetable_id = sub_json_object.getString("from_vegetable_id");
                            ent.last_work_time = "0";
                            ent.user_work_qty = "0";
                            ent.update_time = String.valueOf(Common.GetTimeStamp10());

                            //下载封面图
                            String face_image_url = ent.face_image_url;
                            if (face_image_url.startsWith("/"))
                                face_image_url = Common.File_Server_Url + face_image_url;
                            String url_file_name1 = ent.face_image_url.substring(ent.face_image_url.lastIndexOf("/") + 1);
                            //ent.face_image_url = Common.GetFilesUrl(context) + "/" + url_file_name1;
                            ent.face_image_url = Common.GetCacheFilesUrl(this, url_file_name1);
                            DownFileObject obj = new DownFileObject(face_image_url, ent.face_image_url);
                            local_file_list.add(obj);
                            //启动线程将图片文件下载到本地缓存
                            DownFileThread down = new DownFileThread(this, face_image_url, obj, true);
                            down.start();

                            dao.Insert(ent.table_name, ent.GetInsertContentValues());
                        }
                        init_data_progress += progress_value;
                        String msg = "{\"progress\":"+init_data_progress+"}";
                        EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                        EventBus.getDefault().post(e);


                    }
                } catch (Exception ex) {
                    SaveLog("保存t_vegetable_info表出错：" + ex.getMessage());
                }
                if (page_index < page_count) {
                    int start = page_index + 1;
                    String api_url = "?txt_type=/potnew/init_data/&save_type=t_vegetable_info&start=" + start + "&limit=10";
                    HttpGet(api_url, 0);
                } else {
                    init_data_progress = 99;
                    String msg = "{\"progress\":"+init_data_progress+"}";
                    EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
                    EventBus.getDefault().post(e);
                    CheckDownFileFinish();
                }
                return;
            }

            //要求同步的菜谱内容
            if (save_type.equals("sync_t_company_vegetable_info")) {
                int data_size = Integer.parseInt(Common.JSON_GetFieldValue(json_data, "data_size"));
                String sync_key = Common.JSON_GetFieldValue(json_data, "sync_key");
                SaveLog("远程同步更新了" + data_size + "个菜谱");
                try {
                    JSONObject json_object = new JSONObject(json_data);
                    JSONArray json_array = json_object.getJSONArray("data");
                    for (int i = 0; i < json_array.length(); i++) {
                        //主表
                        JSONObject sub_json_object = json_array.getJSONObject(i);
                        t_vegetable_info ent = new t_vegetable_info();
                        ent.vegetable_id = sub_json_object.getString("vegetable_id");
                        WebUtil.GetSQLData_Vegetable_Delete(this, "1", ent.vegetable_id, "");

                        ent.company_id = sub_json_object.getString("company_id");
                        ent.parent_company_id = sub_json_object.getString("parent_company_id");
                        ent.vegetable_name = sub_json_object.getString("vegetable_name");
                        ent.work_time = sub_json_object.getString("work_time");
                        ent.sort_index = sub_json_object.getString("sort_index");
                        ent.push_src = sub_json_object.getString("push_src");
                        ent.face_image_url = sub_json_object.getString("face_image_url");
                        ent.spec_data = sub_json_object.getJSONArray("spec_data").toString();
                        ent.firsh_char = sub_json_object.getString("firsh_char").toString();
                        ent.from_vegetable_id = sub_json_object.getString("from_vegetable_id");
                        ent.last_work_time = "0";
                        ent.user_work_qty = "0";
                        ent.update_time = String.valueOf(Common.GetTimeStamp10());

                        //下载封面图
                        String face_image_url = ent.face_image_url;
                        if (face_image_url.startsWith("/"))
                            face_image_url = Common.File_Server_Url + face_image_url;
                        String url_file_name1 = ent.face_image_url.substring(ent.face_image_url.lastIndexOf("/") + 1);
                        //ent.face_image_url = Common.GetFilesUrl(context) + "/" + url_file_name1;
                        ent.face_image_url = Common.GetCacheFilesUrl(this, url_file_name1);
                        DownFileObject obj = new DownFileObject(face_image_url, ent.face_image_url);
                        local_file_list.add(obj);
                        //启动线程将图片文件下载到本地缓存
                        DownFileThread down = new DownFileThread(this, face_image_url, obj, true);
                        down.start();
                        dao.Insert(ent.table_name, ent.GetInsertContentValues());
                        SaveLog("sync,vegetable_id=" + ent.vegetable_id);
                    }

                    String api_url = "?txt_type=/potnew/init_data/&save_type=sync_result&status=1&device_id=" + activity_device_id + "&sync_key=" + sync_key;
                    HttpGet(api_url, 0);
                } catch (Exception ex) {
                    SaveLog("保存sync_t_company_vegetable_info表出错：" + ex.getMessage());
                    String api_url = "?txt_type=/potnew/init_data/&save_type=sync_result&status=2&device_id=" + activity_device_id + "&sync_key=" + sync_key;
                    HttpGet(api_url, 0);
                }

                String msg = "{\"msg\":\"远程同步更新了" + data_size + "个菜谱\"}";
                EventMessage e = new EventMessage(EventMessage.MSG_ID_OnSyncVegetable, msg);
                EventBus.getDefault().post(e);
                return;
            }

        }catch (Exception ex1){
            SaveLog("ApplicationClass.OnHttpData出错：save_type=" + save_type + ",json_data=" + json_data + ",error=" + ex1.getMessage());
        }

    }


    //上报故障记录
    public void PutError(String error_code, String error_type, String error_desc) {
        try {
            String api_url2 = "?txt_type=/potnew/put_error/&save_type=save&device_id=" + activity_device_id
                    + "&error_code=" + error_code
                    + "&error_type=" + URLEncoder.encode(error_type)
                    + "&error_desc=" + URLEncoder.encode(error_desc)
                    + "&error_time=" + Common.GetTimeStamp13();
            HttpPost(api_url2, "", 0);
        }catch (Exception ex2)
        {
            SaveLog("ApplicationClass.PutError上报故障记录出错：" + ex2.getMessage());
        }
    }


    //http get异步，通过EventBus返回event_id
    public void HttpGet(String url, int event_id) {
        try {
            HttpThread get = new HttpThread(this, url, event_id);
            get.start();
        }catch (Exception ex){
        }
    }

    //http post异步，通过EventBus返回event_id
    public void HttpPost(String url, String data, int event_id) {
        try {
            HttpThread post = new HttpThread(this, url, event_id, data);
            post.start();
        }catch (Exception ex){
        }
    }

    //http get本地异步
    private String http_long_url = "";
    private void HttpGet(String short_url, String http_callback_tag) {
        http_long_url = Common.API_Server_Url;
        if (short_url.trim().startsWith("?") == false)
            http_long_url += "?";
        if (short_url.trim().toLowerCase().startsWith("http") == false)
            http_long_url += short_url;


        new Thread() {
            @Override
            public void run() {
                String tag = http_callback_tag;
                String return_json = "";
                int error_code = 0;      //0表示没有发生异异，1表示有异常
                try
                {
                    URL url = new URL(http_long_url);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    InputStream is = conn.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                    StringBuilder builder = new StringBuilder();
                    String line = "";
                    while ((line = reader.readLine()) != null) {
                        builder.append(line);
                    }
                    return_json = builder.toString();
                    is.close();
                    conn.disconnect();
                }
                catch(Exception ex)
                {
                    return_json = "error=" + ex.getMessage();
                }
                Message msg = new Message();
                msg.what = MsgID_OnHttpGet;
                Bundle data = new Bundle();
                data.putString("return",return_json);
                data.putString("tag",tag);
                msg.setData(data);
                handler.sendMessage(msg);
            }
        }.start();
    }

    //判断初始化阶段要下载的文件是否完成
    private void CheckDownFileFinish()
    {
        //初始化状态才计算进度和自动下载
        if (ui_status == UI_STATUS_InitData) {
            int exists_file_count = 0;
            String afile = "";
            for (int i=0; i < local_file_list.size(); i++)
            {
                DownFileObject obj = (DownFileObject)local_file_list.get(i);
                if (obj.is_down || Common.CheckLocalFileIsExists(obj.local_file_path))
                    exists_file_count++;
                else
                    afile = obj.local_file_path;
            }
            String text = "一共" + local_file_list.size() + "个图片，已下载" + exists_file_count;
            SaveLog(text);
            if (exists_file_count < local_file_list.size())
            {
                Message msg = new Message();
                msg.what = MsgID_CheckDownFileFinish;
                handler.sendMessageDelayed(msg, 500);
                return;
            }
            init_data_progress = 100;
            String msg = "{\"progress\":"+init_data_progress+"}";
            EventMessage e = new EventMessage(EventMessage.MSG_ID_InitProgress, msg);
            EventBus.getDefault().post(e);
            ui_status = UI_STATUS_Index;
            DeviceStatus = 1;   //进入自检
            ui_status_begin_time = Common.GetTimeStamp13();
            //保存本地缓存
            WebUtil.SaveCacheData(this,"activity_device_id", activity_device_id);
            WebUtil.SaveCacheData(this,"activity_hardware_version", activity_hardware_version);
            WebUtil.SaveCacheData(this,"activity_software_version", activity_software_version);
            //打开首页UI界面
            //web_view.loadUrl(ac.web_page_url_index);   这一步无法打开，所以让H5端重定向到首页了
            SaveLog("初始化完毕");
            try {
                //启动socket长连接
                //SocketAPI_Start();
                //初始化科大讯飞离线语音合成TTS开发包
                //TTS_Init();
                //读取系统参数并上报
                is_need_put_param = true;
                com.ReadHoldingRegister(0x01, 0x0000, 0x6D);

            }
            catch (Exception ex)
            {}
        }
    }

    //消息处理
    @SuppressLint("HandlerLeak")
    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg == null)
                return;
            switch (msg.what) {
                case MsgID_CheckSelfStatus:
                    MsgID_CheckSelfStatus();
                    break;
                case MsgID_CheckDownFileFinish:
                    CheckDownFileFinish();
                    break;
                case MsgID_OnHttpGet:
                    Bundle data = msg.getData();
                    String tag = data.getString("tag");
                    String return_data = data.getString("return");
                    if (tag.equals("login"))
                        APP_LoginResponse(return_data);
                    break;
                case MsgID_SocketData:
                    String socket_data = (String)msg.obj;
                    MainForm_OnSocketData(socket_data);
                    break;
                default:
                    break;
            }
        }
    };

    //读取自检状态0x003B
    private void MsgID_CheckSelfStatus(){
        try {
            com.ReadHoldingRegister(0x01, 0x003B, 0x0001);
        }catch (Exception ex) {
        }
    }

    /**
     * socket收到的数据进行处理
     * @param json_data 收到的数据，json格式
     */
    private void MainForm_OnSocketData(String json_data)
    {
        String cmd = Common.JSON_GetFieldValue(json_data, "cmd");
        String data = Common.JSON_GetFieldValue(json_data, "data");
        //同步pad端的菜谱
        if (cmd.equals("synchronization"))
        {
            String sync_key = Common.JSON_GetFieldValue(json_data, "sync_key");
            data = data.replace("_", ",");
            String api_url = "?txt_type=/potnew/init_data/&save_type=sync_t_company_vegetable_info&sync_key="+sync_key+"&vegetable_id_list=" + data;
            HttpGet(api_url, 0);
        }

    }


    //APP，初始化
    public void APP_Init(){
        try {
            if (DeviceStatus > 1)
                DeviceStatus = 1;     //进入自检
            CheckSelfStatus = 0;      //未开始自检
            iap_status = 0;
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            if (setting3position_list != null)
                setting3position_list.clear();
            //手动炒菜和自动炒菜清空
            handmaster = null;
            jobmaster = null;
            app_is_release = false;
        } catch (Exception ex) {
        }
    }
    //APP，释放
    public void APP_Release() {
        try {
            app_is_release = true;
            android.os.Process.killProcess(android.os.Process.myPid());
        } catch (Exception ex) {
        }
    }


    //APP登录，异步
    public void APP_Login(String account, String password){
        try {
            String api_url = "?txt_type=/potnew/login/login/&username=" + URLEncoder.encode(account) + "&password=" + URLEncoder.encode(password) + "&device_id=" + URLEncoder.encode(activity_device_id);
            HttpGet(api_url, "login");
        } catch (Exception ex) {
        }
    }
    //登录回调
    private void APP_LoginResponse(String return_json) {
        try {
            String result = Common.JSON_GetFieldValue(return_json, "result");
            if (result.equals("true")) {
                this.account = account;
                this.token = Common.JSON_GetFieldValue(return_json, "token");
                this.user_type = Common.JSON_GetFieldValue(return_json, "user_type");
                this.company_id = Common.JSON_GetFieldValue(return_json, "company_id");
                this.parent_company_id = Common.JSON_GetFieldValue(return_json, "parent_company_id");
                if (this.company_id.length() == 0) this.company_id = "0";
                if (this.parent_company_id.length() == 0) this.parent_company_id = "0";
                this.IsLogin = true;
                //保存到缓存
                WebUtil.SaveCacheData(this, "user_token", token);
                WebUtil.SaveCacheData(this, "user_account", account);
                WebUtil.SaveCacheData(this, "user_type", user_type);
                WebUtil.SaveCacheData(this, "user_company_id", company_id);
                WebUtil.SaveCacheData(this, "user_parent_company_id", parent_company_id);
                //每次登录都要马上进化初始化
                Device_InitData();
                //启动socket长连接
                SocketAPI_Start();

                //发消息通知UI界面
                String str1 = "{\"result\":true}";
                EventMessage msg1 = new EventMessage(EventMessage.MSG_ID_LoginResult, str1);
                EventBus.getDefault().post(msg1);
                return;
            }
        } catch (Exception ex) {
        }
        //发消息通知UI界面
        String str2 = "{\"result\":false}";
        EventMessage msg2 = new EventMessage(EventMessage.MSG_ID_LoginResult, str2);
        EventBus.getDefault().post(msg2);
    }

    //APP退出登录
    public boolean APP_Logout() {
        try {
            this.IsLogin = false;
            this.token = "";
            this.account = "";
            this.user_type = "0";
            this.ui_status = UI_STATUS_NeedLogin;
            this.DeviceStatus = -1;
            this.CheckSelfStatus = 0;
            //清空到缓存
            WebUtil.SaveCacheData(this, "user_token", token);
            WebUtil.SaveCacheData(this, "user_account", account);
            WebUtil.SaveCacheData(this, "user_type", user_type);
            //删除sqlite
            //dao.DropData();

            return true;
        } catch (Exception ex) {
            SaveLog("APP_Logout出错：" + ex.getMessage());
        }
        return false;
    }

    //开始自检
    public void Device_SendCommand_0x00E0(){
        SaveLog("Device_SendCommand_0x00E0()");
        //先往0x00E0地址写0x5A，让设备自动复位，等于自检
        try {
            //跳过主板对接
            if (is_test == true) {
                CheckSelfStatus = 2;    //完成自检
                DeviceStatus = 2;       //可以进入首页
                return;
            }


            //自检进行中
            DeviceStatus = 1;
            CheckSelfStatus = 1;
            CheckSelfStatus_BeginTime = Common.GetTimeStamp13();
            CheckSelfStatus_LastTime = CheckSelfStatus_BeginTime;
            //写入串口
            com.writeSingleRegister(0x01, 0x00E0, 0x5A, null);
            //500ms后读1次0x003B
            Message msg1 = new Message();
            msg1.what = MsgID_CheckSelfStatus;
            handler.sendMessageDelayed(msg1, 500);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_0x00E0()出错：" + ex.getMessage());
        }
    }

    //结束自检了
    public void Device_Stop_0x00E0()
    {
        CheckSelfStatus = 0;
    }

    //手动自检--图1发送指令
    public void Device_SendCommand_HandCheck_Image1(int event, int type){
        String event2 = "";
        String type2 = "";
        if (event == 1) event2 = "按下";
        if (event == 2) event2 = "抬起";
        if (type == 1) type2 = "向上";
        if (type == 2) type2 = "向下";
        if (type == 3) type2 = "投菜复位";
        SaveLog("Device_SendCommand_HandCheck_Image1("+event2+","+type2+")");
        try {
            //按下向上
            if (event == 1 && type == 1)
                com.writeSingleRegister(0x01, 0x1000, 0x402, null);
            //抬起向上
            if (event == 2 && type == 1)
                com.writeSingleRegister(0x01, 0x1000, 0x400, null);
            //按下向下
            if (event == 1 && type == 2)
                com.writeSingleRegister(0x01, 0x1000, 0x401, null);
            //抬起向下
            if (event == 2 && type == 2)
                com.writeSingleRegister(0x01, 0x1000, 0x400, null);
            //投菜复位
            if (event == 1 && type == 3) {
                MsgID_CheckSelf_Reset2_IsSend = 0;
                com.writeSingleRegister(0x01, 0x1001, 0x5A04, null);
            }
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_HandCheck_Image1("+event+","+type+")出错：" + ex.getMessage());
        }
    }

    //手动自检--图2发送指令
    public void Device_SendCommand_HandCheck_Image2(int event, int type){
        String event2 = "";
        String type2 = "";
        if (event == 1) event2 = "按下";
        if (event == 2) event2 = "抬起";
        if (type == 1) type2 = "向前";
        if (type == 2) type2 = "向后";
        if (type == 3) type2 = "料盒复位";
        SaveLog("Device_SendCommand_HandCheck_Image2("+event2+","+type2+")");
        try {
            //按下向前
            if (event == 1 && type == 1)
                com.writeSingleRegister(0x01, 0x1000, 0x202, null);
            //抬起向前
            if (event == 2 && type == 1)
                com.writeSingleRegister(0x01, 0x1000, 0x200, null);
            //按下向后
            if (event == 1 && type == 2)
                com.writeSingleRegister(0x01, 0x1000, 0x201, null);
            //抬起向后
            if (event == 2 && type == 2)
                com.writeSingleRegister(0x01, 0x1000, 0x200, null);
            //料盒复位
            if (event == 1 && type == 3) {
                MsgID_CheckSelf_Reset3_IsSend = 0;
                com.writeSingleRegister(0x01, 0x1001, 0x5A02, null);
            }
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_HandCheck_Image2("+event+","+type+")出错：" + ex.getMessage());
        }
    }

    //手动自检--图345发送指令
    public void Device_SendCommand_HandCheck_Image345(int event, int type){
        String event2 = "";
        String type2 = "";
        if (event == 1) event2 = "按下";
        if (event == 2) event2 = "抬起";
        if (type == 1) type2 = "机械臂往上";
        if (type == 2) type2 = "机械臂往下";
        if (type == 3) type2 = "锅往上";
        if (type == 4) type2 = "锅往下";
        if (type == 5) type2 = "转锅顺时针";
        if (type == 6) type2 = "转锅逆时针";
        if (type == 7) type2 = "机械臂复位";
        if (type == 8) type2 = "锅复位";
        SaveLog("Device_SendCommand_HandCheck_Image345("+event2+","+type2+")");
        try {
            //按下机械臂往上
            if (event == 1 && type == 1)
                com.writeSingleRegister(0x01, 0x1000, 0x302, null);
            //抬起机械臂往上
            if (event == 2 && type == 1)
                com.writeSingleRegister(0x01, 0x1000, 0x300, null);
            //按下机械臂往下
            if (event == 1 && type == 2)
                com.writeSingleRegister(0x01, 0x1000, 0x301, null);
            //抬起机械臂往下
            if (event == 2 && type == 2)
                com.writeSingleRegister(0x01, 0x1000, 0x300, null);
            //按下锅往上
            if (event == 1 && type == 3)
                com.writeSingleRegister(0x01, 0x1000, 0x102, null);
            //抬起锅往上
            if (event == 2 && type == 3)
                com.writeSingleRegister(0x01, 0x1000, 0x100, null);
            //按下锅往下
            if (event == 1 && type == 4)
                com.writeSingleRegister(0x01, 0x1000, 0x101, null);
            //抬起锅往下
            if (event == 2 && type == 4)
                com.writeSingleRegister(0x01, 0x1000, 0x100, null);
            //按下转锅顺时针
            if (event == 1 && type == 5)
                com.writeSingleRegister(0x01, 0x1000, 0x503, null);
            //抬起转锅顺时针
            if (event == 2 && type == 5)
                com.writeSingleRegister(0x01, 0x1000, 0x500, null);
            //按下转锅逆时针
            if (event == 1 && type == 6)
                com.writeSingleRegister(0x01, 0x1000, 0x513, null);
            //抬起转锅逆时针
            if (event == 2 && type == 6)
                com.writeSingleRegister(0x01, 0x1000, 0x500, null);
            //机械臂复位
            if (event == 1 && type == 7) {
                MsgID_CheckSelf_Reset0_IsSend = 0;
                com.writeSingleRegister(0x01, 0x1001, 0x5A03, null);
            }
            //锅复位
            if (event == 1 && type == 8) {
                MsgID_CheckSelf_Reset1_IsSend = 0;
                com.writeSingleRegister(0x01, 0x1001, 0x5A01, null);
            }
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_HandCheck_Image345("+event+","+type+")出错：" + ex.getMessage());
        }
    }

    //手动自检--自转寻位
    public void Device_SendCommand_HandCheck_Page3(){
        SaveLog("Device_SendCommand_HandCheck_Page3()");
        try {
            MsgID_CheckSelf_Reset5_IsSend = 0;
            com.writeSingleRegister(0x01, 0x1000, 0x5AA5, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_HandCheck_Page3()出错：" + ex.getMessage());
        }
    }


    //读取首页菜谱列表
    public String GetSQLData_Vegetable_List(int count)
    {
        DeviceStatus = 2;  //代表APP已进入首页了
        SaveLog("GetSQLData_Vegetable_List()-->company_id=" + this.company_id + ",parent_company_id=" + this.parent_company_id);
        String return_data = WebUtil.GetSQLData_Vegetable_List(this, count);
        SaveLog("GetSQLData_Vegetable_List("+count+")=" + return_data);

        //计算料管清清是否在指定的时间区间内，每日只提示1次
        GetSQLData_Cleaning_Nozzle_AutoJob();

        return return_data;
    }

    //读取菜谱详情（用于浏览和炒菜）
    public String GetSQLData_Vegetable_Entity(int vegetable_id)
    {
        String return_data = WebUtil.GetSQLData_Vegetable_Entity(this, String.valueOf(vegetable_id));
        SaveLog("GetSQLData_Vegetable_Entity("+vegetable_id+")=" + return_data);
        return return_data;
    }
    //读取菜谱详情（用于编辑）
    public String GetSQLData_Vegetable_Entity_For_Edit(int vegetable_id)
    {
        String return_data = WebUtil.GetSQLData_Vegetable_Entity_For_Edit(this, String.valueOf(vegetable_id));
        SaveLog("GetSQLData_Vegetable_Entity_For_Edit("+vegetable_id+")=" + return_data);
        return return_data;
    }

    //读取最近使用的词
    public String GetSQLData_Vegetable_Search_GetText(int count)
    {
        String return_data = WebUtil.GetSQLData_Vegetable_Search_GetText(this, count);
        SaveLog("GetSQLData_Vegetable_Search_GetText("+count+")=" + return_data);

        return return_data;
    }

    //搜索系统菜谱
    public String GetSQLData_Vegetable_Search(int search_type, String search_data, int count, String search_char)
    {
        String return_data = WebUtil.GetSQLData_Vegetable_Search(this, search_type, search_data, count, search_char);
        SaveLog("GetSQLData_Vegetable_Search("+search_type+")=" + return_data);

        return return_data;
    }

    //立即炒制
    //vegetable_id  菜谱id
    //spec_id       规格id
    public boolean Cooking_Start(int vegetable_id, int spec_id)
    {
        t_vegetable_info tb = new t_vegetable_info();
        tb.vegetable_id = "" + vegetable_id;
        tb.last_work_time = String.valueOf(Common.GetTimeStamp13());
        dao.ExecSQL(tb.update_work_sql, tb.GetUpdateWorkValues());
        SaveLog("Cooking_Start("+vegetable_id+","+spec_id+")");
        //TTS_Speak("开始烹饪");

        try {
            //读取通用配置
            String public_config = dao.GetPublicConfig();
            //读取系统菜谱详情
            String json_data = WebUtil.GetSQLData_Vegetable_Entity(this, tb.vegetable_id);
            JSONObject json_object = new JSONObject(json_data);
            JSONObject data_object = json_object.getJSONObject("data");
            //上报炒菜数据
            try {

                String api_url2 = "?txt_type=/potnew/put_cooking/&save_type=save&device_id=" + activity_device_id
                        + "&vegetable_id=" + vegetable_id
                        + "&vegetable_name=" + URLEncoder.encode(data_object.getString("vegetable_name"))
                        + "&time=" + Common.GetTimeStamp13();
                HttpGet(api_url2, 0);
            } catch (Exception ex2) {
                SaveLog("Cooking_Start("+vegetable_id+","+spec_id+")上报炒菜数据出错：" + ex2.getMessage());
            }

            //读取全部规格
            JSONArray spec_data = data_object.getJSONArray("spec_data");
            JSONObject spec_object = null;
            for (int i=0; i<spec_data.length(); i++){
                if (spec_data.getJSONObject(i).getString("spec_id").equals("" + spec_id)) {
                    spec_object = spec_data.getJSONObject(i);
                    break;
                }
            }
            if (spec_object == null) {
                SaveLog("Cooking_Start("+vegetable_id+","+spec_id+")规格id不正确");
                return false;
            }

            //创建自动炒菜任务
            jobmaster = new CookingMaster(this, spec_object, 1);

            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_Start("+vegetable_id+","+spec_id+")出错：" + ex.getMessage());
        }

        return false;
    }

    //终止炒菜（炒菜完成）
    public void Cooking_Stop() {
        SaveLog("Cooking_Stop()");
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            if (setting3position_list != null)
                setting3position_list.clear();
            //停止
            if (jobmaster != null)
                jobmaster.Stop();
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_Stop()出错：" + ex.getMessage());
        }
    }

    //终止炒菜（立即退出）
    public void Cooking_Stop_Quickly() {
        SaveLog("Cooking_Stop_Quickly()");
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            if (setting3position_list != null)
                setting3position_list.clear();
            //停止
            if (jobmaster != null)
                jobmaster.Stop_Quickly();
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_Stop_Quickly()出错：" + ex.getMessage());
        }
    }

    //出菜
    public boolean Cooking_PourOut() {
        SaveLog("Cooking_PourOut()");
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            //判断锅位
            if (pot_position_value != 2) {
                //com.writeSingleRegister(0x01, 0x00DC, 0x02, null);
                com.writeSingleRegister(0x01, 0x00E0, 0x5B01, null);
            }
            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_PourOut()出错：" + ex.getMessage());
        }
        return true;
    }


    //立即炒制--读取火力配置
    //vegetable_id  菜谱id
    //spec_id       规格id
    public String GetSQLData_Cooking_Config_Fire(int vegetable_id, int spec_id)
    {
        SaveLog("GetSQLData_Cooking_Config_Fire("+vegetable_id+","+spec_id+")");
        try {
            //读取系统菜谱详情
            t_vegetable_info tb = new t_vegetable_info();
            tb.vegetable_id = "" + vegetable_id;
            String json_data = WebUtil.GetSQLData_Vegetable_Entity(this, tb.vegetable_id);
            JSONObject json_object = new JSONObject(json_data);
            JSONObject data_object = json_object.getJSONObject("data");

            //读取全部规格
            JSONArray spec_data = data_object.getJSONArray("spec_data");
            JSONObject spec_object = null;
            for (int i=0; i<spec_data.length(); i++){
                if (spec_data.getJSONObject(i).getString("spec_id").equals("" + spec_id)) {
                    spec_object = spec_data.getJSONObject(i);
                    break;
                }
            }

            if (spec_object == null) {
                SaveLog("GetSQLData_Cooking_Config_Fire("+vegetable_id+","+spec_id+")规格id不正确");
                return "{\"success\":false,\"desc\":\"规格id不正确\"}";
            }
            JSONArray steep_data = spec_object.getJSONArray("steep_data");
            int total_time = spec_object.getInt("end_time");

            //对步骤里的开始时间进行自然排序
            List<Map.Entry<Integer, JSONObject>> tree_map = new ArrayList<>();
            for (int i=0; i<steep_data.length(); i++)
                tree_map.add(new AbstractMap.SimpleEntry<>(steep_data.getJSONObject(i).getInt("time_long"), steep_data.getJSONObject(i)));
            // 排序
            tree_map.sort(Comparator.comparing(Map.Entry::getKey));

            //将相同开始时间的步骤归入同一步骤
            int steep_index = 1, time_value_old = -1, id = 0;
            Map<Integer, CookingDetail> steep_map = new HashMap<>();
            for (Map.Entry<Integer, JSONObject> entry : tree_map) {
                id++;
                CookingDetail detail_ent;
                CookingSteep steep_ent = new CookingSteep(this, entry.getValue(), steep_index, id);
                if (time_value_old < 0 || steep_ent.time_long == time_value_old) {
                    if (steep_map.containsKey(steep_index))
                        detail_ent = steep_map.get(steep_index);
                    else {
                        detail_ent = new CookingDetail(steep_index);
                        steep_map.put(steep_index, detail_ent);
                        time_value_old = steep_ent.time_long;
                        SaveLog("put1-->steep_index=" + steep_index);
                    }
                }else {
                    steep_index++;
                    detail_ent = new CookingDetail(steep_index);
                    steep_map.put(steep_index, detail_ent);
                    SaveLog("put2-->steep_index=" + steep_index);
                    time_value_old = steep_ent.time_long;
                }
                detail_ent.AddSteep(steep_ent);
            }

            //再遍历一遍，设置每个集合的总时长
            for (int i=2; i<=steep_map.size(); i++){
                //SaveLog("i=" + i);
                CookingDetail detail_ent1 = steep_map.get(i-1);
                CookingDetail detail_ent2 = steep_map.get(i);
                //if (detail_ent1 == null) SaveLog("detail_ent1=null");
                //if (detail_ent2 == null) SaveLog("detail_ent2=null");
                detail_ent1.total_time = detail_ent2.time_long - detail_ent1.time_long;
                if (i == steep_map.size())
                    detail_ent2.total_time = total_time - detail_ent2.time_long;
            }
            if (steep_map.size() == 1) {
                CookingDetail detail_ent1 = steep_map.get(1);
                detail_ent1.total_time = total_time;
                SaveLog("total_time=" + total_time);
            }

            //输出json结构
            json_data = "";
            for (int i=1; i<=steep_map.size(); i++)
            {
                CookingDetail ent = steep_map.get(i);
                long remain_time = ent.total_time - ent.pass_time;
                if (remain_time < 0)
                    remain_time = 0;
                String sub_data = "{\"steep_index\":" + ent.steep_index
                        + ",\"title1\":\"" + ent.steep_index + "·" + ent.steep_name + "\""
                        + ",\"title2\":\"加热时长\""
                        + ",\"unit\":\"s\""
                        + ",\"value\":" + ent.total_time
                        + ",\"min_value\":0"
                        + ",\"max_value\":" + (ent.total_time * 2)
                        + ",\"step_value\":1";
                if (ent.steep_name.contains("料盒"))
                    sub_data += ",\"is_show\":0}";
                else
                    sub_data += ",\"is_show\":1}";
                if (json_data.length() > 0)
                    json_data += ",";
                json_data += sub_data;
            }
            json_data = "{\"success\":true,\"data\":[" + json_data + "]}";
            SaveLog("GetSQLData_Cooking_Config_Fire()-->" + json_data);
            return json_data;
        }
        catch (Exception ex)
        {
            SaveLog("GetSQLData_Cooking_Config_Fire("+vegetable_id+","+spec_id+")出错：" + ex.getMessage());
        }

        return "{\"success\":false,\"desc\":\"失败\"}";
    }

    //立即炒制--读取口味配置
    //vegetable_id  菜谱id
    //spec_id       规格id
    public String GetSQLData_Cooking_Config_Nozzle(int vegetable_id, int spec_id)
    {
        SaveLog("GetSQLData_Cooking_Config_Nozzle("+vegetable_id+","+spec_id+")");
        try {
            //读取系统菜谱详情
            t_vegetable_info tb = new t_vegetable_info();
            tb.vegetable_id = "" + vegetable_id;
            String json_data = WebUtil.GetSQLData_Vegetable_Entity(this, tb.vegetable_id);
            JSONObject json_object = new JSONObject(json_data);
            JSONObject data_object = json_object.getJSONObject("data");

            //读取全部规格
            JSONArray spec_data = data_object.getJSONArray("spec_data");
            JSONObject spec_object = null;
            for (int i=0; i<spec_data.length(); i++){
                if (spec_data.getJSONObject(i).getString("spec_id").equals("" + spec_id)) {
                    spec_object = spec_data.getJSONObject(i);
                    break;
                }
            }
            if (spec_object == null) {
                SaveLog("GetSQLData_Cooking_Config_Nozzle("+vegetable_id+","+spec_id+")规格id不正确");
                return "{\"success\":false,\"desc\":\"规格id不正确\"}";
            }
            JSONArray steep_data = spec_object.getJSONArray("steep_data");
            int total_time = spec_object.getInt("end_time");
            //对步骤里的开始时间进行自然排序
            List<Map.Entry<Integer, JSONObject>> tree_map = new ArrayList<>();
            for (int i=0; i<steep_data.length(); i++)
                tree_map.add(new AbstractMap.SimpleEntry<>(steep_data.getJSONObject(i).getInt("time_long"), steep_data.getJSONObject(i)));
            // 排序
            tree_map.sort(Comparator.comparing(Map.Entry::getKey));
            //将相同开始时间的步骤归入同一步骤
            int steep_index = 1, time_value_old = -1, id = 0;
            Map<Integer, CookingDetail> steep_map = new HashMap<>();
            for (Map.Entry<Integer, JSONObject> entry : tree_map) {
                id++;
                CookingDetail detail_ent;
                CookingSteep steep_ent = new CookingSteep(this, entry.getValue(), steep_index, id * 100);
                if (time_value_old < 0 || steep_ent.time_long == time_value_old) {
                    if (steep_map.containsKey(steep_index))
                        detail_ent = steep_map.get(steep_index);
                    else {
                        detail_ent = new CookingDetail(steep_index);
                        steep_map.put(steep_index, detail_ent);
                        time_value_old = steep_ent.time_long;
                    }
                }else {
                    steep_index++;
                    detail_ent = new CookingDetail(steep_index);
                    steep_map.put(steep_index, detail_ent);
                    time_value_old = steep_ent.time_long;
                }
                detail_ent.AddSteep(steep_ent);
            }
            //再遍历一遍，设置每个集合的总时长
            for (int i=2; i<=steep_map.size(); i++){
                CookingDetail detail_ent1 = steep_map.get(i-1);
                CookingDetail detail_ent2 = steep_map.get(i);
                detail_ent1.total_time = detail_ent2.time_long - detail_ent1.time_long;
                if (i == steep_map.size())
                    detail_ent2.total_time = total_time - detail_ent2.time_long;
            }
            if (steep_map.size() == 1) {
                CookingDetail detail_ent1 = steep_map.get(1);
                detail_ent1.total_time = total_time;
            }
            //输出json结构
            json_data = "";
            int index = 0;
            for (int i=1; i<=steep_map.size(); i++)
            {
                CookingDetail ent = steep_map.get(i);
                if (ent.is_contains_nozzle) {
                    index++;
                    String sub_data1 = "{\"steep_index\":" + ent.steep_index
                            + ",\"title1\":\"第"+index+"次投料\"";
                    String steep_data2 = "";
                    for (int j=0; j<ent.list.size(); j++) {
                        CookingSteep sub_ent = ent.list.get(j);
                        if (sub_ent.steep_type == 2) {
                            for (int n=1; n<=11; n++) {
                                int nozzle_value = 0;
                                if (n == 1) nozzle_value = sub_ent.nozzle1_value;
                                if (n == 2) nozzle_value = sub_ent.nozzle2_value;
                                if (n == 3) nozzle_value = sub_ent.nozzle3_value;
                                if (n == 4) nozzle_value = sub_ent.nozzle4_value;
                                if (n == 5) nozzle_value = sub_ent.nozzle5_value;
                                if (n == 6) nozzle_value = sub_ent.nozzle6_value;
                                if (n == 7) nozzle_value = sub_ent.nozzle7_value;
                                if (n == 8) nozzle_value = sub_ent.nozzle8_value;
                                if (n == 9) nozzle_value = sub_ent.nozzle9_value;
                                if (n == 10) nozzle_value = sub_ent.nozzle10_value;
                                if (n == 11) nozzle_value = sub_ent.nozzle11_value;
                                if (nozzle_value > 0) {
                                    String sub_data2 = "{\"id\":" + (sub_ent.id + n)
                                            + ",\"title2\":\"" + Common.nozzle_name_list[n] + "\""
                                            + ",\"unit\":\"g\""
                                            + ",\"value\":" + nozzle_value
                                            + ",\"min_value\":0"
                                            + ",\"max_value\":" + (nozzle_value * 2)
                                            + ",\"step_value\":1}";
                                    if (steep_data2.length() > 0)
                                        steep_data2 += ",";
                                    steep_data2 += sub_data2;
                                }
                            }
                        }
                    }
                    sub_data1 += ",\"steep_data\":["+steep_data2+"]}";
                    if (json_data.length() > 0)
                        json_data += ",";
                    json_data += sub_data1;
                }
            }
            json_data = "{\"success\":true,\"data\":[" + json_data + "]}";

            return json_data;
        }
        catch (Exception ex)
        {
            SaveLog("GetSQLData_Cooking_Config_Nozzle("+vegetable_id+","+spec_id+")出错：" + ex.getMessage());
        }

        return "{\"success\":false,\"desc\":\"失败\"}";
    }

    //读取新的菜谱名称
    public String GetSQLData_Cooking_Config_NewName(int vegetable_id) {
        return WebUtil.GetSQLData_Cooking_Config_NewName(this, vegetable_id);
    }

    //保存菜谱副本
    //data1  火力
    //data2  口味
    public String SaveSQLData_Cooking_Config_CopyNew(int vegetable_id, int spec_id, JSONObject data1, JSONObject data2, String vegetable_name) {
        SaveLog("SaveSQLData_Cooking_Config_CopyNew("+vegetable_id+","+spec_id+","+vegetable_name+")");
        try {
            //火力输入值合法性判断
            if (data1 != null) {
                for (int i = 0; i < data1.getJSONArray("data").length(); i++) {
                    if (data1.getJSONArray("data").getJSONObject(i).getInt("value") <= 0)
                        return "{\"success\":false,\"desc\":\"火力的第" + data1.getJSONArray("data").getJSONObject(i).getString("steep_index") + "步设置值不能为0\"}";
                }
            }
            //口味输入值合法性判断
            if (data2 != null) {
                for (int i = 0; i < data2.getJSONArray("data").length(); i++) {
                    for (int j = 0; j < data2.getJSONArray("data").getJSONObject(i).getJSONArray("steep_data").length(); j++) {
                        if (data2.getJSONArray("data").getJSONObject(i).getJSONArray("steep_data").getJSONObject(j).getInt("value") <= 0)
                            return "{\"success\":false,\"desc\":\"口味的第" + data2.getJSONArray("data").getJSONObject(i).getString("steep_index") + "步设置值不能为0\"}";
                    }
                }
            }

            //复制一个菜+规格，生成另一个新菜
            //String return_data = WebUtil.SaveSQLData_Cooking_Config_CopyNew(this, vegetable_id, spec_id, vegetable_name);
            //JSONObject return_obj = new JSONObject(return_data);
            //if (return_obj.getBoolean("success")) {
                t_vegetable_info tb = new t_vegetable_info();
                tb.vegetable_id = "" + vegetable_id;  //return_obj.getString("vegetable_id");
                //tb.face_image_url = return_obj.getString("face_image_url");
                String json_data = WebUtil.GetSQLData_Vegetable_Entity(this, tb.vegetable_id);
                JSONObject json_object = new JSONObject(json_data);
                tb.face_image_url = json_object.getJSONObject("data").getString("face_image_url");
                JSONArray spec_data = json_object.getJSONObject("data").getJSONArray("spec_data");
                JSONObject spec_object = null;
                for (int i=0; i<spec_data.length(); i++){
                    if (spec_data.getJSONObject(i).getString("spec_id").equals("" + spec_id)) {
                        spec_object = spec_data.getJSONObject(i);
                        break;
                    }
                }
                if (spec_object == null) {
                    SaveLog("SaveSQLData_Cooking_Config_CopyNew("+vegetable_id+","+spec_id+")规格id不正确");
                    return "{\"success\":false,\"desc\":\"规格id不正确\"}";
                }

                //火力
                if (data1 != null) {
                    //SaveLog("spec_data1=" + spec_data.toString());
                    //Log.d("spec_data1=" ,"spec_data1= "+ spec_data.toString());
                    int total_time = 0;
                    for (int i = 0; i < data1.getJSONArray("data").length(); i++) {
                        int value = data1.getJSONArray("data").getJSONObject(i).getInt("value");
                        if (value < 1)
                            value = 1;
                        //SaveLog("total_time=" + total_time + ",value=" + value);
                        spec_object.getJSONArray("steep_data").getJSONObject(i).put("time_long", total_time);
                        spec_object.getJSONArray("steep_data").getJSONObject(i).put("time_value", Common.int2time(total_time));
                        total_time += value;
                    }
                    spec_object.put("end_time", total_time);
                    //SaveLog("spec_data2=" + spec_data.toString());
                    //Log.d("spec_data2=" ,"spec_data2= "+ spec_data.toString());
                }
                //口味
                if (data2 != null) {
                    int j=-1;
                    for (int i = 0; i < spec_object.getJSONArray("steep_data").length(); i++) {
                        if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("steep_type") == 2) {
                            j++;
                            int n = -1;
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle1_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle1_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle2_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle2_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle3_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle3_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle4_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle4_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle5_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle5_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle6_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle6_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle7_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle7_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle8_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle8_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle9_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle9_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle10_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle10_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                            if (spec_object.getJSONArray("steep_data").getJSONObject(i).getInt("nozzle11_value") > 0) {
                                n++;
                                spec_object.getJSONArray("steep_data").getJSONObject(i).put("nozzle11_value", data2.getJSONArray("data").getJSONObject(j).getJSONArray("steep_data").getJSONObject(n).getInt("value"));
                            }
                        }
                    }
                }

                tb.spec_data = spec_data.toString();
                dao.ExecSQL(tb.update_spec_sql3, tb.GetUpdateSpecValues3());

                return "{\"success\":true,\"desc\":\"保存成功\",\"vegetable_id\":"+tb.vegetable_id+",\"spec_id\":"+spec_id+"}";
            //}
        }
        catch(Exception ex)
        {
            SaveLog("SaveSQLData_Cooking_Config_CopyNew("+vegetable_id+","+spec_id+","+vegetable_name+")出错：" + ex.getMessage());
        }
        return "{\"success\":false,\"desc\":\"保存失败\",\"vegetable_id\":0,\"spec_id\":0}";
    }


    //读取洗锅配置列表
    public String GetSQLData_Cleaning_List()
    {
        SaveLog("GetSQLData_Cleaning_List()");

        try {
            //读取洗锅配置
            String clean_config = dao.GetCleanConfig();
            JSONObject json_object = new JSONObject(clean_config);
            JSONArray clean1_data = json_object.getJSONArray("clean1_data");
            JSONArray clean2_data = json_object.getJSONArray("clean2_data");
            JSONArray clean3_data = json_object.getJSONArray("clean3_data");
            JSONArray clean4_data = json_object.getJSONArray("clean4_data");
            String item1 = CleanData_GetJson(clean1_data.getJSONObject(0), 1);
            String item2 = CleanData_GetJson(clean2_data.getJSONObject(0), 2);
            String item3 = CleanData_GetJson(clean3_data.getJSONObject(0), 3);
            String item4 = CleanData_GetJson(clean4_data.getJSONObject(0), 4);
            String return_json = "{\"success\":true,\"item_count\":4,\"item_data\":[" + item1 + "," + item2 + "," + item3 + "," + item4 + "]}";
            return return_json;
        }
        catch (Exception ex)
        {
            SaveLog("GetSQLData_Cleaning_List()出错：" + ex.getMessage());
        }

        return "{\"success\":false,\"item_count\":0,\"item_data\":[]}";
    }
    //获取精简版的json
    private String CleanData_GetJson(JSONObject clean_object, int type){
        String return_json = "{}";
        try {
            String time = clean_object.getString("end_time");
            String name = "快速洗";
            if (type == 2) name = "常规洗";
            if (type == 3) name = "强力洗";
            if (type == 4) name = "自定义清洗";
            String water = clean_object.getJSONArray("steep_data").getJSONObject(1).getString("nozzle9_value");
            int fire_value = clean_object.getJSONArray("steep_data").getJSONObject(0).getInt("fire_value");
            String hot = "0";
            if (fire_value > 0)
                hot = clean_object.getJSONArray("steep_data").getJSONObject(2).getString("time_long");
            return_json = "{\"type\":"+type+",\"name\":\""+name+"\",\"time\":"+time+",\"water\":"+water+",\"hot\":"+hot+"}";
        }
        catch (Exception ex)
        {
            SaveLog("CleanData_GetJson("+type+")出错：" + ex.getMessage());
        }
        return return_json;
    }
    //获取精简版的json
    private String BringData_GetJson(JSONObject clean_object, int type){
        String return_json = "{}";
        try {
            String time = clean_object.getString("end_time");
            String name = "快速养锅";
            if (type == 2) name = "普通养锅";
            if (type == 3) name = "加强养锅";
            if (type == 4) name = "自定义养锅";
            String oil = clean_object.getJSONArray("steep_data").getJSONObject(1).getString("nozzle5_value");
            int fire_value = clean_object.getJSONArray("steep_data").getJSONObject(0).getInt("fire_value");
            String hot = "0";
            if (fire_value > 0)
                hot = clean_object.getJSONArray("steep_data").getJSONObject(2).getString("time_long");
            return_json = "{\"type\":"+type+",\"name\":\""+name+"\",\"time\":"+time+",\"oil\":"+oil+",\"hot\":"+hot+"}";
        }
        catch (Exception ex)
        {
            SaveLog("BringData_GetJson("+type+")出错：" + ex.getMessage());
        }
        return return_json;
    }

    //自动洗锅
    //type 洗锅方式：1快速洗、2普通洗、3加强洗、4自定义清洗
    public boolean Cleaning_Start(int type) {
        SaveLog("Cleaning_Start("+type+")");
        //TTS_Speak("开始洗锅");

        try {
            //读取洗锅配置
            String clean_config = dao.GetCleanConfig();
            JSONObject json_object = new JSONObject(clean_config);
            JSONArray clean_data = json_object.getJSONArray("clean1_data");
            if (type == 2) clean_data = json_object.getJSONArray("clean2_data");
            if (type == 3) clean_data = json_object.getJSONArray("clean3_data");
            if (type == 4) clean_data = json_object.getJSONArray("clean4_data");
            if (clean_data == null) {
                SaveLog("Cleaning_Start("+type+")参数不正确");
                return false;
            }
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle1_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle2_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle3_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle4_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle5_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle6_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle7_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle8_value", 0);
            //clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle9_value", 0);
            //2025.05.08  黎工要求洗锅功能将洗锅水改为烹饪水
            //int nozzle9_value = clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).getInt("nozzle9_value");
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle10_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle11_value", 0);


            //创建自动洗锅任务
            jobmaster = new CookingMaster(this, clean_data.getJSONObject(0), 2);
            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Cleaning_Start("+type+")出错：" + ex.getMessage());
        }
        return false;
    }

    //终止洗锅
    public void Cleaning_Stop() {
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            if (setting3position_list != null)
                setting3position_list.clear();
            //停止
            jobmaster.Stop();
        }
        catch (Exception ex)
        {
            SaveLog("Cleaning_Stop()出错：" + ex.getMessage());
        }
    }

    //例水
    public boolean Cleaning_PourOut() {
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            //判断锅位
            if (pot_position_value != 1) {
                com.writeSingleRegister(0x01, 0x00DC, 0x01, null);
            }
            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_PourOut()出错：" + ex.getMessage());
        }
        return true;
    }






    //设置机械臂和爪子
    //gripper_position_value 机械臂位置，1放下、2抬起
    public void GripperSetting(int gripper_position_value, int gripper_rotation_value, int gripper_speed_value) {
        try {
            this.gripper_rotation_value = gripper_rotation_value;
            this.gripper_speed_value = gripper_speed_value;
            //如果当前机械臂已放下了，则马上发指令
            if (this.gripper_position_value == 1 && this.gripper_position_value == gripper_position_value) {
                gripper_is_setting = false;
                //机械爪转向，0正方向、1反方向、2周期正反转
                com.writeSingleRegister(0x01, 0x00E2, gripper_rotation_value, null);
                //机械爪转速，0-5档
                com.writeSingleRegister(0x01, 0x00E1, gripper_speed_value, null);
                return;
            }
            //机械臂位置，1放下、2抬起
            com.writeSingleRegister(0x01, 0x00DF, gripper_position_value, null);
            if (gripper_position_value == 1) {
                gripper_is_setting = true;
                gripper_setting_time = Common.GetTimeStamp13();
            } else {
                gripper_is_setting = false;
            }
        }
        catch (Exception ex)
        {
            SaveLog("GripperSetting("+gripper_position_value+","+gripper_rotation_value+","+gripper_speed_value+")出错：" + ex.getMessage());
        }
    }

    //炒菜前要设置3个位：机械臂=放下位、锅=原位、料盒轨=第1位、机械爪0档
    public void Cooking_Setting3Position(String obj_name) {
        try {
            if (setting3position_list != null)
                setting3position_list.clear();
            else
                setting3position_list = new ArrayList<>();
            //机械爪转速，0档
            com.writeSingleRegister(0x01, 0x00E1, 0x00, null);
            //2025.05.09  黎工说可以往0x00E0地址写入0x5A01实现3大件全部归位
            //com.writeSingleRegister(0x01, 0x00E0, 0x5A01, null);


            //锅位
            if (pot_position_value != 3) {
                com.writeSingleRegister(0x01, 0x00DC, 0x03, null);
                SteepCheckNode node = new SteepCheckNode("pot_position_value", 0x03, true, 0, 0);
                setting3position_list.add(node);
            }
            //机械臂
            if (gripper_position_value != 1) {
                if (setting3position_list.size() == 0) {
                    com.writeSingleRegister(0x01, 0x00DF, 0x01, null);
                    SteepCheckNode node = new SteepCheckNode("gripper_position_value", 0x01, true, 0, 0);
                    setting3position_list.add(node);
                } else {
                    SteepCheckNode node = new SteepCheckNode("gripper_position_value", 0x01, false, 0x00DF, 0x01);
                    setting3position_list.add(node);
                }
            }
            //料盒轨
            if (box_position_value != 1) {
                if (setting3position_list.size() == 0) {
                    com.writeSingleRegister(0x01, 0x00DE, 0x01, null);
                    SteepCheckNode node = new SteepCheckNode("box_position_value", 0x01, true, 0, 0);
                    setting3position_list.add(node);
                } else {
                    SteepCheckNode node = new SteepCheckNode("box_position_value", 0x01, false, 0x00DE, 0x01);
                    setting3position_list.add(node);
                }
            }

            setting3position_name = obj_name;
            setting3position_time = Common.GetTimeStamp13();
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_Setting3Position("+gripper_position_value+","+gripper_rotation_value+","+gripper_speed_value+")出错：" + ex.getMessage());
        }
    }
    //炒菜中要投放第n个料盒
    public void Cooking_SettingBoxPosition(int box_index, int box_release_type) {
        try {
            //料盒轨
            if (box_position_value != box_index) {
                setting_box_time = Common.GetTimeStamp13();
                setting_box_index = box_index;
                setting_box_release_type = box_release_type;
                com.writeSingleRegister(0x01, 0x00DE, box_index, null);
            } else {
                setting_box_time = 0;
                setting_box_index = 0;
                setting_box_release_type = 0;
                //投菜
                if (box_release_type > 0)
                    com.writeSingleRegister(0x01, 0x00DD, box_release_type, null);
            }
        }
        catch (Exception ex)
        {
            SaveLog("Cooking_SettingBoxPosition("+box_index+","+box_release_type+")出错：" + ex.getMessage());
        }
    }

    //手动炒制--读取7处组合列表
    //type=1手动炒制、2自动录制
    public String GetSQLData_Handing_Config(int type) {
        return WebUtil.GetSQLData_Handing_Config_Format(this, type);
    }

    //手动炒制--开始
    public boolean Handing_Start()
    {
        SaveLog("Handing_Start()");
        //TTS_Speak("手动烹饪");

        try {
            //创建手动炒菜任务
            handmaster = new HandingMaster(this);
            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Start()出错：" + ex.getMessage());
        }
        return false;
    }

    //终止手动炒菜
    public void Handing_Stop() {
        SaveLog("Handing_Stop()");
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            //停止
            handmaster.Stop();
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Stop()出错：" + ex.getMessage());
        }
    }

    //手动炒制--设置火力  0-9档
    public void Handing_Setting_Fire(int fire_value){
        SaveLog("Handing_Setting_Fire("+fire_value+")");
        try {
            if (0 <= fire_value && fire_value <= 9) {
                com.writeSingleRegister(0x01, 0x00FD, fire_value, null);
                //录制
                handmaster.current_entity.fire_value = fire_value;
                handmaster.AddRecording(1);  //1加热设置
            }
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Setting_Fire("+fire_value+")出错：" + ex.getMessage());
        }
    }

    //手动炒制--设置机械臂和揽拌子
    public void Handing_Setting_Gripper(int position_value, int rotation_value, int speed_value){
        SaveLog("Handing_Setting_Gripper("+position_value+","+rotation_value+","+speed_value+")");
        try {
            GripperSetting(position_value, rotation_value, speed_value);
            //录制
            handmaster.current_entity.gripper_position_value = position_value;
            handmaster.current_entity.gripper_rotation_value = rotation_value;
            handmaster.current_entity.gripper_speed_value = speed_value;
            handmaster.AddRecording(1);  //1加热设置
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Setting_Gripper()出错：" + ex.getMessage());
        }
    }

    //手动炒制--设置锅位
    //锅位置：1洗锅位、2出菜位、3炒菜位
    public void Handing_Setting_PotPosition(int position_value){
        SaveLog("Handing_Setting_PotPosition("+position_value+")-->now_value=" + pot_position_value + ",old_value=" + pot_position_value_old);
        try {
            if (1 <= position_value && position_value <= 3)
                com.writeSingleRegister(0x01, 0x00DC, position_value, null);
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Setting_PotPosition("+position_value+")出错：" + ex.getMessage());
        }
    }

    //手动炒制--开启喷泵（组合）
    //type 工作模式：1手动炒制、2自动录制
    public void Handing_Setting_OpenNozzle(int config_id, int type){
        SaveLog("Handing_Setting_OpenNozzle("+config_id+","+type+")");
        try {
            String json_str = WebUtil.GetSQLData_Handing_Config_List(this, type);
            JSONObject json_obj = new JSONObject(json_str);
            for (int i=0; i<json_obj.getJSONArray("item_data").length(); i++) {
                if (config_id == json_obj.getJSONArray("item_data").getJSONObject(i).getInt("config_id")) {
                    int nozzle1_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle1_value");
                    int nozzle2_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle2_value");
                    int nozzle3_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle3_value");
                    int nozzle4_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle4_value");
                    int nozzle5_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle5_value");
                    int nozzle6_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle6_value");
                    int nozzle7_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle7_value");
                    int nozzle8_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle8_value");
                    int nozzle9_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle9_value");
                    int nozzle10_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle10_value");
                    int nozzle11_value = json_obj.getJSONArray("item_data").getJSONObject(i).getInt("nozzle11_value");

                    //录制
                    handmaster.current_entity.nozzle1_value = nozzle1_value;
                    handmaster.current_entity.nozzle2_value = nozzle2_value;
                    handmaster.current_entity.nozzle3_value = nozzle3_value;
                    handmaster.current_entity.nozzle4_value = nozzle4_value;
                    handmaster.current_entity.nozzle5_value = nozzle5_value;
                    handmaster.current_entity.nozzle6_value = nozzle6_value;
                    handmaster.current_entity.nozzle7_value = nozzle7_value;
                    handmaster.current_entity.nozzle8_value = nozzle8_value;
                    handmaster.current_entity.nozzle9_value = nozzle9_value;
                    handmaster.current_entity.nozzle10_value = nozzle10_value;
                    handmaster.current_entity.nozzle11_value = nozzle11_value;
                    handmaster.AddRecording(2);  //2调味料投放

                    int[] nozzle_values = new int[11];
                    nozzle_values[0] = Common.NozzleControl(nozzle1_value, 1);
                    nozzle_values[1] = Common.NozzleControl(nozzle2_value, 2);
                    nozzle_values[2] = Common.NozzleControl(nozzle3_value, 3);
                    nozzle_values[3] = Common.NozzleControl(nozzle4_value, 4);
                    nozzle_values[4] = Common.NozzleControl(nozzle5_value, 5);
                    nozzle_values[5] = Common.NozzleControl(nozzle6_value, 6);
                    nozzle_values[6] = Common.NozzleControl(nozzle7_value, 7);
                    nozzle_values[7] = Common.NozzleControl(nozzle8_value, 8);
                    nozzle_values[8] = Common.NozzleControl(nozzle9_value, 9);
                    nozzle_values[9] = Common.NozzleControl(nozzle10_value, 10);
                    nozzle_values[10] = Common.NozzleControl(nozzle11_value, 11);
                    for (int j=0; j<nozzle_values.length; j++) {
                        if (nozzle_values[j] > 0)
                            com.writeSingleRegister(0x01, Common.nozzle_address_list[j + 1], nozzle_values[j], null);
                    }
                    nozzle_values = null;

                }
            }
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Setting_OpenNozzle("+config_id+")出错：" + ex.getMessage());
        }
    }


    //手动炒制--投放料盒
    //type 工作模式：1手动炒制、2自动录制
    public void Handing_Setting_ThrowBox(int box_index, int type){
        SaveLog("Handing_Setting_ThrowBox("+box_index+","+type+")");
        try {
            //读取投菜方式配置值
            String json_data = WebUtil.GetSQLData_Handing_Config_Box(this, type);
            SaveLog("Handing_Setting_ThrowBox=" + json_data);
            JSONObject json_object = new JSONObject(json_data);
            int box_release_type = 0x01;
            if (box_index == 1) box_release_type = json_object.getJSONArray("data").getJSONObject(0).getInt("box1_value");
            if (box_index == 2) box_release_type = json_object.getJSONArray("data").getJSONObject(0).getInt("box2_value");
            if (box_index == 3) box_release_type = json_object.getJSONArray("data").getJSONObject(0).getInt("box3_value");
            if (box_index == 4) box_release_type = json_object.getJSONArray("data").getJSONObject(0).getInt("box4_value");
            //设置
            Cooking_SettingBoxPosition(box_index, box_release_type);
            //录制
            handmaster.current_entity.box_index = box_index;
            handmaster.current_entity.box_release_type = box_release_type;
            handmaster.AddRecording(3);  //3料盒投放
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Setting_ThrowBox("+box_index+")出错：" + ex.getMessage());
        }
    }

    //手动炒制--读取料盒投菜方式配置
    //type=1手动炒制、2自动录制
    public String GetSQLData_Handing_Config_Box(int type) {
        return WebUtil.GetSQLData_Handing_Config_Box(this, type);
    }

    //手动炒制--读取料盒投菜方式配置
    //type=1手动炒制、2自动录制
    public void SaveSQLData_Handing_Config_Box(int box1_value, int box2_value, int box3_value, int box4_value, int type) {
        WebUtil.SaveSQLData_Handing_Config_Box(this, box1_value , box2_value, box3_value, box4_value, type);
    }

    //手动炒制--料盒复位
    public void Handing_Setting_ResetBox(){
        SaveLog("Handing_Setting_ResetBox()");
        try {
            Cooking_SettingBoxPosition(0x01, 0x00);
        }
        catch (Exception ex)
        {
            SaveLog("Handing_Setting_ResetBox()出错：" + ex.getMessage());
        }
    }

    //判断机械臂是否可以抬起、放下  name=抬起、放下
    //判断锅口是否可以出菜、倒水、洗锅、炒菜
    //判断菜盒是否可以投料
    public String CheckIsCanMove(String name) {
        //box_position_value  料盒位置：0未初始化、1-4是盒子1-4位置、0xF0运动过程中
        //pot_position_value  锅口位置：0未初始化、1倒水位、2倒菜位、3原位、0xF0运动过程中
        //box_throw_move      料盒投臂状态：0未初始化、1原位、2投菜位、0xF0运动过程中
        //gripper_position_value  机械爪位置，0未初始化、1放下、2抬起、0xF0运动过程中

        String tishi1 = "运动中，请稍候再按";
        if (box_position_value > 10 || pot_position_value > 10 || box_throw_move >= 2 || gripper_position_value > 10)
            return tishi1;

        //抬起、放下点击过快的计算
        if (name.equals("抬起") || name.equals("放下")) {
            long now = Common.GetTimeStamp13();
            if (now - gripper_throw_last_time < 5000)
                return "操作过快";
            gripper_throw_last_time = now;
        }
        //判断机械臂是否可以抬起
        if (name.equals("抬起")) {
            if (box_throw_move == 2)
                return tishi1;
        }
        //判断机械臂是否可以放下
        if (name.equals("放下")) {
            if (box_throw_move == 2)
                return tishi1;
            if (pot_position_value != 3)
                return "锅未到炒菜位";
        }
        //判断锅口是否可以出菜、倒水、洗锅、炒菜
        if (name.equals("出菜")) {
            long now = Common.GetTimeStamp13();
            if (now - box_move_last_time < 3000)
                return "操作过快";
            box_move_last_time = now;

        }
        //投料
        if (name.equals("投料") || name.equals("投放")) {
            long now = Common.GetTimeStamp13();
            if (now - box_throw_last_time < 3000)
                return "投料过快";
            box_throw_last_time = now;

            if (pot_position_value != 3)
                return "锅未到炒菜位";
        }

        return "";
    }


    //判断手动炒菜是否可以关闭界面退出，返回true允许退出
    public boolean CheckIsCanClose() {
        //box_position_value  料盒轨位置：0未初始化、1-4是盒子1-4位置、0xF0运动过程中
        //pot_position_value  锅口位置：0未初始化、1倒水位、2倒菜位、3原位、0xF0运动过程中
        //box_throw_move      料盒投臂状态：0未初始化、1原位、2投菜位、0xF0运动过程中
        //gripper_position_value  机械臂位置，0未初始化、1放下、2抬起、0xF0运动过程中
        //gripper_position_status 机械爪寻位状态，0未初始化、1在原点、2运动过程中、3暂停中、0xF0寻位过程中

        if (box_position_value == 0xF0 || pot_position_value == 0xF0 || box_throw_move == 0xF0 || gripper_position_value == 0xF0 || gripper_position_status == 0xF0)
            return false;

        return true;
    }


    //读取喷泵组合配置
    //type=1手动炒制、2自动录制
    public String GetSQLData_Handing_Config_Nozzle_Entity(int config_id, int type) {
        SaveLog("GetSQLData_Handing_Config_Nozzle_Entity(" + config_id + "," + type + ")");
        String rtn = WebUtil.GetSQLData_Handing_Config_Nozzle_Entity(this, config_id, type);
        return rtn;
    }

    //保存喷泵组合配置
    //type=1手动炒制、2自动录制
    public boolean SaveSQLData_Handing_Config_Nozzle_Entity(int config_id, int nozzle1_value, int nozzle2_value, int nozzle3_value, int nozzle4_value, int nozzle5_value, int nozzle6_value, int nozzle7_value, int nozzle8_value, int nozzle9_value, int nozzle10_value, int nozzle11_value, int type) {
        SaveLog("SaveSQLData_Handing_Config_Nozzle_Entity(" + config_id
                + "," + nozzle1_value
                + "," + nozzle2_value
                + "," + nozzle3_value
                + "," + nozzle4_value
                + "," + nozzle5_value
                + "," + nozzle6_value
                + "," + nozzle7_value
                + "," + nozzle8_value
                + "," + nozzle9_value
                + "," + nozzle10_value
                + "," + nozzle11_value
                + "," + type + ")");
        return WebUtil.SaveSQLData_Handing_Config_Nozzle_Entity(this, config_id, nozzle1_value, nozzle2_value, nozzle3_value, nozzle4_value, nozzle5_value, nozzle6_value, nozzle7_value, nozzle8_value, nozzle9_value, nozzle10_value, nozzle11_value, type);
    }

    //判断APP是否有新版本
    public void GetAppUpgradeUrl(){
        String api_url = "?txt_type=/potnew/init_data/&save_type=check_app_upgrade&device_id=" + activity_device_id + "&app_version=" + APP_Version;
        HttpGet(api_url, EventMessage.MSG_ID_OnHttpData_APP);
    }

    //判断IAP是否有新版本
    public void GetIAPUpgradeUrl(){
        String api_url = "?txt_type=/potnew/init_data/&save_type=check_iap_upgrade&device_id=" + activity_device_id;
        HttpGet(api_url, EventMessage.MSG_ID_OnHttpData_IAP);
    }

    //获取共享图片
    public void GetShareImage(int start, int limit, String share_name){
        String api_url = "?txt_type=/potnew/share_image/&save_type=search&token=" + token + "&start=" + start + "&limit=" + limit + "&search_name=" + URLEncoder.encode(share_name);
        HttpGet(api_url, EventMessage.MSG_ID_OnHttpData_Image);
    }

    //开始安装IAP新版bin包
    public boolean IAP_InstallStart(String file_path) {
        if (iap_status != 0)
            return false;
        SaveLog("IAP_InstallStart(" + file_path + ")开始");
        try {
            iap_file_data = Common.GetFile(file_path);
            if (iap_file_data == null || iap_file_data.length == 0)
                return false;
            //开始升级
            iap_status = 1;   //0表示没有升级，1表示升级中，2表示已发送完文件等待重启
            iap_eot_count = 0;
            iap_file_crc_value = 0;
            iap_file_crc_value = CRC16.CRC16_XMODEM_Part(iap_file_data, iap_file_data.length, iap_file_crc_value);
            iap_pack_count = iap_file_data.length / 1024;
            if (iap_file_data.length % 1024 > 0)
                iap_pack_count++;
            iap_pack_index = -1;
            iap_is_wait_0x43 = true;
            //先往0xFFFF地址写入0x5BB5
            com.writeSingleRegister(1, 0xFFFF, 0x5BB5, null);

            return true;
        } catch (Exception ex) {
            iap_status = 0;
            SaveLog("IAP_InstallStart(" + file_path + ")出错：" + ex.getMessage());
        }
        return false;
    }
    //串口收到升级包的ACK回复，则继续发下一帧
    private void IAP_Install_SendNextFrame() {
        if (iap_status != 1)
            return;
        try {
            iap_pack_index++;
            if (iap_pack_index == 0) {
                SaveLog("IAP_Install_SendNextFrame(" + iap_pack_count + "," + iap_pack_index + ")");
                //再发送IAP升级第1帖：文件信息
                com.sender.AddSendData(Ymodem.sendFileInfoPacket("aa.bin", iap_file_data.length, iap_file_crc_value), 0, 0);
                return;
            }

            if (iap_pack_index <= iap_pack_count) {
                SaveLog("IAP_Install_SendNextFrame(" + iap_pack_count + "," + iap_pack_index + ")");
                byte[] buffer = new byte[1024];
                int pack_size = 1024;
                if (iap_pack_index < iap_pack_count) {
                    System.arraycopy(iap_file_data, (iap_pack_index - 1) * 1024, buffer, 0, buffer.length);
                    com.sender.AddSendData(Ymodem.sendDataPacket(Ymodem.STX, iap_pack_index, buffer), 0, 0);
                } else if (iap_pack_index == iap_pack_count) {
                    pack_size = iap_file_data.length % 1024;
                    SaveLog("pack_size=" + pack_size);
                    if (pack_size > 128 || pack_size == 0) {
                        for (int i = pack_size; i < 1024; i++)
                            buffer[i] = (byte) 0x1A;
                        System.arraycopy(iap_file_data, (iap_pack_index - 1) * 1024, buffer, 0, pack_size);
                        com.sender.AddSendData(Ymodem.sendDataPacket(Ymodem.STX, iap_pack_index, buffer), 0, 0);
                    } else {
                        //128字节以内的包只发128长度
                        for (int i = pack_size; i < 128; i++)
                            buffer[i] = (byte) 0x1A;
                        System.arraycopy(iap_file_data, (iap_pack_index - 1) * 1024, buffer, 0, pack_size);
                        byte[] buffer2 = new byte[128];
                        System.arraycopy(buffer, 0, buffer2, 0, buffer2.length);
                        com.sender.AddSendData(Ymodem.sendDataPacket(Ymodem.SOH, iap_pack_index, buffer2), 0, 0);
                        buffer2 = null;
                    }
                }
                buffer = null;

                String msg1 = "{\"max_value\":"+iap_pack_count+",\"cur_value\":"+iap_pack_index+"}";
                EventMessage e1 = new EventMessage(EventMessage.MSG_ID_IAP_InstallProgress, msg1);
                EventBus.getDefault().post(e1);
            } else {
                if (iap_eot_count == 0) {
                    //发第1帧EOT
                    iap_eot_count++;
                    SaveLog("IAP_Install_SendNextFrame(EOT-1)");
                    com.sender.AddSendData(new byte[]{0x04}, 0, 0);
                } else if (iap_eot_count == 1) {
                    //发第2帧EOT
                    iap_eot_count++;
                    SaveLog("IAP_Install_SendNextFrame(EOT-2)");
                    com.sender.AddSendData(new byte[]{0x04}, 0, 0);
                } else if (iap_eot_count == 2) {
                    //发结束帧
                    iap_eot_count++;
                    SaveLog("IAP_Install_SendNextFrame(END)");
                    com.sender.AddSendData(Ymodem.sendEndPacket(), 0, 0);
                } else {
                    SaveLog("IAP_Install_SendNextFrame(Finish)");
                    //APP变量初始化，5秒后UI界面将进入自检界面
                    APP_Init();
                    activity_software_version = "";
                    EventMessage e2 = new EventMessage(EventMessage.MSG_ID_IAP_InstallFinish, "ok");
                    EventBus.getDefault().post(e2);
                }
            }
        } catch (Exception ex) {
            iap_status = 0;
            String msg3 = "{\"error\":\""+ex.getMessage().replace("\"", "")+"\"}";
            EventMessage e3 = new EventMessage(EventMessage.MSG_ID_IAP_InstallError, msg3);
            EventBus.getDefault().post(e3);
            SaveLog("IAP_Install_SendNextFrame(" + iap_pack_count + "," + iap_pack_index + "," + iap_eot_count + ")出错：" + ex.getMessage());
        }
    }

    //取消安装IAP新版bin包
    public void IAP_InstallCancel() {
        iap_status = 0;
    }


    //获取调味料校准列表
    public String GetSQLData_Calibration_List() {
        try {
            //黎工说这里要给炒菜爪子发提台指令
            com.writeSingleRegister(0x01, 0x00E0, 0x5A02, null);
        } catch (Exception ex){
        }
        return WebUtil.GetSQLData_Calibration_List(this);
    }

    //校准界面--长按投料
    public void Calibration_Control_Nozzle(int nozzle_id, int control_value) {
        SaveLog("Calibration_Control_Nozzle("+nozzle_id+","+control_value+")");
        try {
            //2025.06.14  泵id改变了，这里做个转换
            nozzle_id = Common.nozzle_id_list[nozzle_id];
            //开泵
            if (control_value == 1) {
                com.writeSingleRegister(0x01, 0x00F1 + nozzle_id, 2, null);
            }
            //关泵
            if (control_value == 0) {
                com.writeSingleRegister(0x01, 0x00F1 + nozzle_id, 0, null);
            }
        } catch (Exception ex) {
            SaveLog("Calibration_Control_Nozzle("+nozzle_id+","+control_value+")出错：" + ex.getMessage());
        }
    }

    //校准界面--开始校准
    public void Calibration_Control_Begin(int nozzle_id) {
        SaveLog("Calibration_Control_Begin("+nozzle_id+")");
        try {
            //2025.06.14  泵id改变了，这里做个转换
            nozzle_id = Common.nozzle_id_list[nozzle_id];
            int[] data = new int[2];
            data[0] = nozzle_id;
            data[1] = 0x5A;
            com.writeHoldingRegisters(0x01, 0xE6, 2, data);
        } catch (Exception ex) {
            SaveLog("Calibration_Control_Begin("+nozzle_id+")出错：" + ex.getMessage());
        }
    }

    //校准界面--开始投料
    public void Calibration_Control_Spray(int index) {
        SaveLog("Calibration_Control_Spray("+index+")");
        try {
            com.writeSingleRegister(0x01, 0x00E8, index, null);
        } catch (Exception ex) {
            SaveLog("Calibration_Control_Spray("+index+")出错：" + ex.getMessage());
        }
    }

    //校准界面--保存重量
    public void Calibration_Control_Weight(float value) {
        SaveLog("Calibration_Control_Weight("+value+")");
        try {
            int value2 = (int)(value * 10);
            if (value2 >= 0 && value2 <= 9999)
                com.writeSingleRegister(0x01, 0x00E9, value2, null);
        } catch (Exception ex) {
            SaveLog("Calibration_Control_Weight("+value+")出错：" + ex.getMessage());
        }
    }

    //油灌加热--获取值
    public boolean OilBoxIsHeat_GetValue() {
        if (activity_oil_box_is_heat.equals("1"))
            return true;
        else
            return false;
    }

    //油灌加热--保存值
    public void OilBoxIsHeat_SaveValue(boolean value) {
        if (value)
            activity_oil_box_is_heat = "1";
        else
            activity_oil_box_is_heat = "0";
        WebUtil.SaveCacheData(this, "activity_oil_box_is_heat", activity_oil_box_is_heat);
        //这里要发指令给设备
        OilBoxIsHeat_SendCommand();
    }

    //油灌加热--发指令
    public void OilBoxIsHeat_SendCommand() {
        try {
            if (activity_oil_box_is_heat.equals("1"))
                com.writeSingleRegister(0x01, 0x00F6, 0x5A, null);  //开
            else
                com.writeSingleRegister(0x01, 0x00F6, 0x5B, null);  //关
        } catch (Exception ex) {
            SaveLog("OilBoxIsHeat_SendCommand()出错：" + ex.getMessage());
        }
    }

    //首页菜谱份数排序--获取值
    public boolean GetSQLData_GetOrderBy() {
        if (activity_vegetable_order_by.equals("1"))
            return true;
        else
            return false;
    }

    //首页菜谱份数排序--保存值
    public void SaveSQLData_SaveOrderBy(boolean value) {
        if (value)
            activity_vegetable_order_by = "1";
        else
            activity_vegetable_order_by = "0";
        WebUtil.SaveCacheData(this, "activity_vegetable_order_by", activity_vegetable_order_by);
    }

    //获取自定义洗锅参数
    public String CleanData_Customer_GetData(){
        String return_json = "{\"time\":60,\"water\":1000,\"fire_value\":5,\"gripper_speed_value\":3,\"gripper_rotation_value\":0}";
        try {
            //读取洗锅配置
            String clean_config = dao.GetCleanConfig();
            JSONObject json_object = new JSONObject(clean_config);
            JSONArray clean_data = json_object.getJSONArray("clean4_data");
            JSONArray steep_data = clean_data.getJSONObject(0).getJSONArray("steep_data");

            String time = clean_data.getJSONObject(0).getString("end_time");
            String water = steep_data.getJSONObject(1).getString("nozzle9_value");
            int fire_value = steep_data.getJSONObject(0).getInt("fire_value");
            int gripper_speed_value = steep_data.getJSONObject(0).getInt("gripper_speed_value");
            int gripper_rotation_value = steep_data.getJSONObject(0).getInt("gripper_rotation_value");
            return_json = "{\"time\":"+time+",\"water\":"+water+",\"fire_value\":"+fire_value+",\"gripper_speed_value\":"+gripper_speed_value+",\"gripper_rotation_value\":"+gripper_rotation_value+"}";
        }
        catch (Exception ex)
        {
            SaveLog("CleanData_Customer_GetData()出错：" + ex.getMessage());
        }
        return return_json;
    }

    //保存自定义洗锅参数
    public void CleanData_Customer_SaveData(int time, int water, int fire_value, int gripper_speed_value, int gripper_rotation_value){
        try {
            //读取洗锅配置
            String clean_config = dao.GetCleanConfig();
            JSONObject json_object = new JSONObject(clean_config);
            JSONArray clean_data = json_object.getJSONArray("clean4_data");
            JSONArray steep_data = clean_data.getJSONObject(0).getJSONArray("steep_data");

            int time2 = time; // - 2;
            if (time2 < 2) {
                time = 2;
                time2 = 2;
            }
            clean_data.getJSONObject(0).put("end_time", time);
            //steep_data.getJSONObject(0).put("time_long", time);
            //steep_data.getJSONObject(0).put("time_value", Common.int2time(time));
            steep_data.getJSONObject(1).put("nozzle9_value", water);
            steep_data.getJSONObject(0).put("fire_value", fire_value);
            steep_data.getJSONObject(0).put("gripper_speed_value", gripper_speed_value);
            steep_data.getJSONObject(0).put("gripper_rotation_value", gripper_rotation_value);
            steep_data.getJSONObject(2).put("time_long", time2);
            steep_data.getJSONObject(2).put("time_value", Common.int2time(time2));

            t_public_config_clean ent = new t_public_config_clean();
            ent.clean4_data = clean_data.toString();
            dao.ExecSQL(ent.update_sql, ent.GetUpdateValues());
        }
        catch (Exception ex)
        {
            SaveLog("CleanData_Customer_SaveData("+time+","+water+","+fire_value+","+gripper_speed_value+","+gripper_rotation_value+")出错：" + ex.getMessage());
        }
    }

    //获取调味料放置列表
    public String GetSQLData_Nozzle_List() {
        return WebUtil.GetSQLData_Nozzle_List(this);
    }

    //获取要清洗的料管名称
    public String GetSQLData_Cleaning_Nozzle_GetNameList()
    {
        return WebUtil.GetSQLData_Cleaning_Nozzle_GetNameList(this);
    }

    //开始清洗料管
    public void GetSQLData_Cleaning_Nozzle_Start()
    {
        try {
            Cleaning_Nozzle_ID_List = "";
            //料管清洗配置表
            t_public_config_clean_nozzle ent = new t_public_config_clean_nozzle();
            long time2 = Common.GetTimeStamp10(Common.GetDataTimeString().substring(0, 11).trim() + " 00:00:00");
            Cursor dt = dao.GetCursor(ent.list_sql, null);
            String item_data = dao.Cursor2Json(dt);
            JSONObject json_object = new JSONObject(item_data);
            for (int i=1; i<=11; i++) {
                int is_nozzle = Integer.parseInt(json_object.getString("is_nozzle" + i));
                int value = Integer.parseInt(json_object.getString("nozzle"+i+"_value"));
                int time1 = Integer.parseInt(json_object.getString("nozzle"+i+"_time"));
                if (is_nozzle == 1 && time2 - time1 >= 3600 * 24 * value) {
                    //更新数据库
                    String update_sql = "update t_public_config_clean_nozzle set nozzle"+i+"_time=" + time2;
                    String[] values = new String[0];
                    dao.ExecSQL(update_sql, values);
                    //发指令
                    com.writeSingleRegister(0x01, 0x00F1 + i, 2, null);
                    //id记录下来
                    if (Cleaning_Nozzle_ID_List.length() > 0)
                        Cleaning_Nozzle_ID_List += ",";
                    Cleaning_Nozzle_ID_List += "" + i;
                }
            }
        }
        catch (Exception ex)
        {
            SaveLog("GetSQLData_Cleaning_Nozzle_Start()出错：" + ex.getMessage());
        }
    }

    //结束清洗料管
    public void GetSQLData_Cleaning_Nozzle_Stop()
    {
        if (Cleaning_Nozzle_ID_List == null || Cleaning_Nozzle_ID_List.length() == 0)
            return;
        try {
            String[] id_list = Cleaning_Nozzle_ID_List.split(",");
            for (int i=0; i<id_list.length; i++) {
                int id = Integer.parseInt(id_list[i]);
                //发指令
                com.writeSingleRegister(0x01, 0x00F1 + id, 0, null);
            }
            Cleaning_Nozzle_ID_List = "";
        }
        catch (Exception ex)
        {
            SaveLog("GetSQLData_Cleaning_Nozzle_Stop()出错：" + ex.getMessage());
        }
    }

    //计算料管清清是否在指定的时间区间内，每日只提示1次
    private void GetSQLData_Cleaning_Nozzle_AutoJob() {
        Context ac = this;
        new Thread() {
            @Override
            public void run() {
                try {
                    long time3 = Long.parseLong(Cleaning_Nozzle_Tishi_Last_Time);
                    long time2 = Common.GetTimeStamp10(Common.GetDataTimeString().substring(0, 10).trim() + " 00:00:00");
                    if (time2 <= time3)
                        return;


                    //SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()----1111");
                    String name_list = "";
                    //料管清洗配置表
                    t_public_config_clean_nozzle ent = new t_public_config_clean_nozzle();
                    Cursor dt = dao.GetCursor(ent.list_sql, ent.GetListValues());
                    //SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()----1111---aaaa");
                    String item_data = dao.Cursor2Json(dt);
                    //SaveLog("item_data----" + item_data);
                    //SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()----1111---bbbb");
                    JSONObject json_object = new JSONObject(item_data);
                    //SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()----1111---cccc");
                    ent.remind_begin_time = json_object.getString("remind_begin_time");
                    ent.remind_end_time = json_object.getString("remind_end_time");
                    long time4 = Common.GetTimeStamp10(Common.GetDataTimeString().substring(0, 10).trim() + " " + ent.remind_begin_time + ":00");
                    long time5 = Common.GetTimeStamp10(Common.GetDataTimeString().substring(0, 10).trim() + " " + ent.remind_end_time + ":00");
                    long time6 = Common.GetTimeStamp10();
                    if (time6 < time4 || time6 > time5)
                        return;
                    //SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()----2222");
                    for (int i = 1; i <= 11; i++) {
                        int is_nozzle = Integer.parseInt(json_object.getString("is_nozzle" + i));
                        int value = Integer.parseInt(json_object.getString("nozzle" + i + "_value"));
                        int time1 = Integer.parseInt(json_object.getString("nozzle" + i + "_time"));
                        if (is_nozzle == 1 && time2 - time1 >= 3600 * 24 * value) {
                            if (name_list.length() > 0)
                                name_list += "、";
                            name_list += "[" + Common.nozzle_name_list[i] + "]";
                        }
                    }
                    //SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()----3333");
                    if (name_list.length() > 0) {
                        Cleaning_Nozzle_Tishi_Last_Time = "" + time2;
                        WebUtil.SaveCacheData(ac, "Cleaning_Nozzle_Tishi_Last_Time", Cleaning_Nozzle_Tishi_Last_Time);
                        //延时300ms再发消息
                        Thread.sleep(300);
                        //发消息通知首页
                        String msg1 = "{\"name\":\""+name_list+"\"}";
                        EventMessage e1 = new EventMessage(EventMessage.MSG_ID_CleaningTishi, msg1);
                        EventBus.getDefault().post(e1);
                    }
                }catch (Exception ex) {
                    SaveLog("GetSQLData_Cleaning_Nozzle_AutoJob()出错：" + ex.getMessage());
                }
            }
        }.start();
    }


    //菜谱研发--菜谱录制--开始录制
    public boolean Developing_Start(JSONObject json_object) {
        SaveLog("Developing_Start(steep_status="+handmaster.steep_status+")-->" + json_object.toString());
        if (handmaster == null || handmaster.steep_status != 1)
            return false;
        try {
            //判断入库的json结构是否正确
            json_object.getString("vegetable_name");
            json_object.getString("face_image_url");
            json_object.getJSONArray("spec_data").getJSONObject(0).getInt("copies_qty");
            json_object.getJSONArray("spec_data").getJSONObject(0).getInt("weight");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(0).getInt("box_index");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(1).getInt("box_index");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(2).getInt("box_index");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(3).getInt("box_index");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(0).put("material_id", "1");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(1).put("material_id", "2");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(2).put("material_id", "3");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(3).put("material_id", "4");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(0).put("spec_id", "1");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(1).put("spec_id", "1");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(2).put("spec_id", "1");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(3).put("spec_id", "1");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(0).put("vegetable_id", "0");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(1).put("vegetable_id", "0");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(2).put("vegetable_id", "0");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(3).put("vegetable_id", "0");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(0).put("create_time", "");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(1).put("create_time", "");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(2).put("create_time", "");
            json_object.getJSONArray("spec_data").getJSONObject(0).getJSONArray("material_data").getJSONObject(3).put("create_time", "");

            handmaster.record_object = json_object;
            //开始
            handmaster.record_status = 1;  //1录制中
            //开始时间
            handmaster.record_begin_time = Common.GetTimeStamp13();
            //创建录制队列
            handmaster.record_map = new HashMap<>();
            //马上添加第1步加热设置
            handmaster.AddRecording(1);  //1加热设置
            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Developing_Start()出错：" + ex.getMessage());
        }
        return false;
    }

    //菜谱研发--菜谱录制--结束录制
    public void Developing_Stop() {
        if (handmaster == null)
            return;
        try {
            //结束
            handmaster.record_status = 2;  //2已结束
            //结束时间
            handmaster.record_end_time = Common.GetTimeStamp13();

        }
        catch (Exception ex)
        {
            SaveLog("Developing_Stop()出错：" + ex.getMessage());
        }
    }

    //菜谱研发--菜谱录制--保存录制
    public String Developing_Save() {
        if (handmaster == null || handmaster.record_status != 2)
            return "";
        SaveLog("Developing_Save()开始");
        try {
            //计算总时长
            long now = Common.GetTimeStamp13();
            long time_long1 = now - handmaster.record_begin_time;
            int time_long2 = (int) (time_long1 / 1000);
            if (time_long1 % 1000 >= 500)
                time_long2++;
            handmaster.record_object.put("work_time", Common.int2time(time_long2));
            handmaster.record_object.put("user_work_qty", "0");
            handmaster.record_object.getJSONArray("spec_data").getJSONObject(0).put("spec_id", "1");
            handmaster.record_object.getJSONArray("spec_data").getJSONObject(0).put("end_time", "" + time_long2);
            handmaster.record_object.getJSONArray("spec_data").getJSONObject(0).put("create_time", Common.GetDataTimeString());
            //生成步骤json
            JSONArray steep_data = new JSONArray();
            for (int i=1; i<=handmaster.record_map.size(); i++) {
                JSONObject sub_obj = new JSONObject(handmaster.record_map.get(i));
                steep_data.put(sub_obj);
            }
            handmaster.record_object.getJSONArray("spec_data").getJSONObject(0).put("steep_data", steep_data);
            //保存
            //判断菜谱名称已存在，则要做菜谱合并
            String vegetable_name = handmaster.record_object.getString("vegetable_name");

            boolean is_exists = GetSQLData_Vegetable_IsExists(0, vegetable_name);
            if (is_exists == true) {
                String data = WebUtil.GetSQLData_Vegetable_Entity_ByName(this, vegetable_name);
                JSONObject old_object = new JSONObject(data);
                int exists_vegetable_id = old_object.getJSONObject("data").getInt("vegetable_id");
                old_object.getJSONObject("data").getJSONArray("spec_data").put(handmaster.record_object.getJSONArray("spec_data").getJSONObject(0));
                SaveLog("Developing_Save()旧菜=" + exists_vegetable_id);
                return WebUtil.SaveSQLData_Handing_Old(this, exists_vegetable_id, old_object.getJSONObject("data"));
            }
            SaveLog("Developing_Save()新菜-->" + handmaster.record_object);
            return WebUtil.SaveSQLData_Handing_New(this, handmaster.record_object);
        }
        catch (Exception ex)
        {
            SaveLog("Developing_Save()出错：" + ex.getMessage());
        }
        return "{\"success\":true,\"desc\":\"成功\",\"vegetable_id\":0,\"spec_id\":0}";
    }

    //菜谱研发--新增菜谱--判断菜谱名称是否存在
    public boolean GetSQLData_Vegetable_IsExists(int vegetable_id, String vegetable_name) {
        String str = WebUtil.GetSQLData_Vegetable_IsExists(this, "" + vegetable_id, vegetable_name);
        if (Common.JSON_GetFieldValue(str, "is_exists").equals("1"))
            return true;
        else
            return false;
    }

    //菜谱研发--新增菜谱--判断菜谱名称+份数是否存在
    //copies_qty份数，1-10
    public boolean GetSQLData_VegetableAndSpec_IsExists(int vegetable_id, String vegetable_name, int copies_qty) {
        String str = WebUtil.GetSQLData_VegetableAndSpec_IsExists(this, "" + vegetable_id, vegetable_name, "" + copies_qty);
        if (Common.JSON_GetFieldValue(str, "is_exists").equals("1"))
            return true;
        else
            return false;
    }

    //菜谱研发--新增菜谱--读取基础食材列表
    public String GetSQLData_Vegetable_List_Base(int count) {
        return WebUtil.GetSQLData_Vegetable_List_Base(this, count);
    }

    //菜谱研发--新增菜谱--保存基础食材
    public boolean SaveSQLData_Vegetable_Base(String base_name) {
        WebUtil.SaveSQLData_Vegetable_Base(this, base_name);
        return true;
    }

    //菜谱研发--新增菜谱--保存新增菜谱
    public String SaveSQLData_Vegetable_Entity(int vegetable_id, JSONObject json_data) {
        SaveLog("SaveSQLData_Vegetable_Entity("+vegetable_id+")开始");
        //对json结构进行格式化处理
        try {
            int max_total_time = 0;
            //遍历规格
            JSONArray spec_array = json_data.getJSONArray("spec_data");
            for (int i=0; i<spec_array.length(); i++) {
                int spec_id = i + 1;
                spec_array.getJSONObject(i).put("spec_id", spec_id);
                spec_array.getJSONObject(i).put("vegetable_id", "0");
                //料盒列表
                JSONArray material_array = new JSONArray();
                //遍历步骤
                int total_time = 0;
                int box_count = 0;
                JSONArray steep_array = spec_array.getJSONObject(i).getJSONArray("steep_data");
                for (int j=0; j<steep_array.length(); j++) {
                    int steep_id = j + 1;
                    steep_array.getJSONObject(j).put("steep_id", steep_id);
                    steep_array.getJSONObject(j).put("steep_index", steep_id);

                    //步骤类型：1加热设置、2调味料投放、3料盒投放、4手动投放
                    int steep_type = steep_array.getJSONObject(j).getInt("steep_type");
                    if (steep_type == 3 && material_array.length() < 4){
                        String box_name = "";
                        String box_weight = "0";
                        JSONArray box_array = steep_array.getJSONObject(j).getJSONArray("box_data");
                        for (int n=0; n<box_array.length(); n++) {
                            if (box_name.length() > 0)
                                box_name += "、";
                            if (n ==  box_array.length() - 1) {
                                box_name += box_array.getJSONObject(n).getString("name");
                                box_weight = box_array.getJSONObject(n).getString("value");
                                if (box_weight.length() == 0)
                                    box_weight = "0";
                                if (Common.IsLong(box_weight) == true) {
                                    box_weight = "" + Long.parseLong(box_weight);
                                    box_array.getJSONObject(n).put("value", box_weight);
                                }
                            } else {
                                box_name += box_array.getJSONObject(n).getString("name") + " " + box_array.getJSONObject(n).getString("value");
                            }
                        }
                        steep_array.getJSONObject(j).put("box1_name", "");
                        steep_array.getJSONObject(j).put("box1_value", "0");
                        steep_array.getJSONObject(j).put("box2_name", "");
                        steep_array.getJSONObject(j).put("box2_value", "0");
                        steep_array.getJSONObject(j).put("box3_name", "");
                        steep_array.getJSONObject(j).put("box3_value", "0");
                        steep_array.getJSONObject(j).put("box4_name", "");
                        steep_array.getJSONObject(j).put("box4_value", "0");
                        int box_index = material_array.length() + 1;
                        JSONObject material_obj = new JSONObject();
                        material_obj.put("box_index", box_index);
                        material_obj.put("material_id", box_index);
                        material_obj.put("spec_id", spec_id);
                        material_obj.put("vegetable_id", "0");
                        material_obj.put("create_time", "");
                        material_obj.put("material_name", box_name);
                        material_obj.put("weight", box_weight);
                        material_array.put(material_obj);
                        steep_array.getJSONObject(j).put("box"+box_index+"_name", box_name);
                        steep_array.getJSONObject(j).put("box"+box_index+"_value", box_weight);
                    }

                    if (steep_type == 1) steep_array.getJSONObject(j).put("tts_text", "加热设置");
                    if (steep_type == 2) steep_array.getJSONObject(j).put("tts_text", "调味料投放");
                    if (steep_type == 3) steep_array.getJSONObject(j).put("tts_text", "料盒投放");
                    if (steep_type == 4) steep_array.getJSONObject(j).put("tts_text", "手动投放");
                    //时长
                    int time_long = steep_array.getJSONObject(j).getInt("time_long");
                    //投诉料盒的时长不能小于8秒
                    if (steep_type == 3 && time_long < 8) {
                        box_count++;
                        time_long = 8;
                        if (box_count > 1)
                            time_long = 13;
                        steep_array.getJSONObject(j).put("time_long", time_long);
                    }
                    //将时长设置为开始时间
                    steep_array.getJSONObject(j).put("time_long", total_time);
                    steep_array.getJSONObject(j).put("time_value", Common.int2time(total_time));
                    //累计时长
                    total_time += time_long;
                }
                if (total_time > max_total_time)
                    max_total_time = total_time;

                //当料盒不够4个时要补齐4个
                for (int m=material_array.length() + 1; m<=4; m++) {
                    int box_index = m;
                    JSONObject material_obj = new JSONObject();
                    material_obj.put("box_index", box_index);
                    material_obj.put("material_id", box_index);
                    material_obj.put("spec_id", spec_id);
                    material_obj.put("vegetable_id", "0");
                    material_obj.put("create_time", "");
                    material_obj.put("material_name", "");
                    material_obj.put("weight", "0");
                    material_array.put(material_obj);
                }
                System.out.print("编辑material_array=" + material_array.toString());
                spec_array.getJSONObject(i).put("material_data", material_array);
                spec_array.getJSONObject(i).put("end_time", total_time);
                spec_array.getJSONObject(i).put("create_time", Common.GetDataTimeString());
            }
            json_data.put("work_time", Common.int2time(max_total_time));

        }catch (Exception ex){
            SaveLog("SaveSQLData_Vegetable_Entity("+vegetable_id+")出错：" + ex.getMessage());
            return "{\"success\":false,\"desc\":\"菜谱结构不正确\",\"vegetable_id\":0,\"spec_id\":0}";
        }
        if (vegetable_id == 0)
            return WebUtil.SaveSQLData_Handing_New(this, json_data);
        else
            return WebUtil.SaveSQLData_Handing_Old(this, vegetable_id, json_data);
    }


    //设置运动电机值--方向
    public void Device_SendCommand_Motor_Direction(int motor_type, int value){
        SaveLog("Device_SendCommand_Motor_Direction("+motor_type+","+value+")");
        try {
            int address = 0x00CA;  //锅
            if (motor_type == 2) address = 0x00CF;  //导轨
            if (motor_type == 3) address = 0x00D4;  //机械臂
            if (motor_type == 4) address = 0x00D9;  //投菜
            com.writeSingleRegister(0x01, address, value, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_Motor_Direction("+motor_type+","+value+")出错：" + ex.getMessage());
        }
    }

    //设置运动电机值--角度
    public void Device_SendCommand_Motor_Angle(int motor_type, float value){
        SaveLog("Device_SendCommand_Motor_Angle("+motor_type+","+value+")");
        try {
            int address = 0x00CB;  //锅
            if (motor_type == 2) address = 0x00D0;  //导轨
            if (motor_type == 3) address = 0x00D5;  //机械臂
            if (motor_type == 4) address = 0x00DA;  //投菜
            int value2 = (int)(value * 10);
            com.writeSingleRegister(0x01, address, value2, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_Motor_Angle("+motor_type+","+value+")出错：" + ex.getMessage());
        }
    }

    //设置运动电机值--控制开关
    public void Device_SendCommand_Motor_Control(int motor_type, int value){
        SaveLog("Device_SendCommand_Motor_Control("+motor_type+","+value+")");
        try {
            int address = 0x00CC;  //锅
            if (motor_type == 2) address = 0x00D1;  //导轨
            if (motor_type == 3) address = 0x00D6;  //机械臂
            if (motor_type == 4) address = 0x00DB;  //投菜
            com.writeSingleRegister(0x01, address, value, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_Motor_Control("+motor_type+","+value+")出错：" + ex.getMessage());
        }
    }

    //1-10号喷泵的重量与耗时计算
    public int Device_Nozzle_Weight_2_Time(int nozzle_index, int weight) {
        if (1 <= nozzle_index && nozzle_index <= 10) {
            double value = Nozzle_Weigth_2_Time[nozzle_index - 1] / 1000.0 * weight;
            return (int)Math.round(value);
        }
        return 0;
    }

    //投放料盒耗时耗时计算
    //box_index   料盒序号，从1至4，一共4个料盒
    //throw_type  投菜方式：1常规投菜（投两下）、2慢速投菜（滞留几秒后归位，不抖动）、3快速投菜（投三下）、4慢速投菜（投三下）
    public int Device_BoxThrow_2_Time(int box_index, int throw_type) {
        /*
        address_0x001C_value;  //爪子原位检测最大时间
        address_0x001D_value;  //臂抬放时间
        address_0x001E_value;  //投菜模式1时间
        address_0x001F_value;  //投菜模式2时间
        address_0x0020_value;  //投菜模式3时间
        address_0x0021_value;  //投菜模式4时间
        address_0x0022_value;  //单料盒运动时间
        address_0x0023_value;  //料盒加减速时间
         */
        int return_value = 8;
        if (throw_type == 1)
            return_value = (int) Math.ceil((address_0x001E_value / 10.0) + ((address_0x0023_value/ 10.0)*2 + 1.3 ) + 0.5);
        if (throw_type == 2)
            return_value = (int) Math.ceil((address_0x001F_value / 10.0) + ((address_0x0023_value/ 10.0)*2 + 1.3 ) + 0.5);
        if (throw_type == 3)
            return_value = (int) Math.ceil((address_0x0020_value / 10.0) + ((address_0x0023_value/ 10.0)*2 + 1.3 ) + 0.5);
        if(box_index==4)
            return_value = (int) Math.ceil((address_0x0021_value / 10.0) + 0.5);
        SaveLog("Device_BoxThrow_2_Time("+box_index+","+throw_type+")=" + return_value);
        return return_value;
    }

    //获取故障记录，start=第n页，默认值为1
    public String GetSQLData_ErrorInfo(String search_code, String search_time, String start, String limit)
    {
        String return_data = WebUtil.GetSQLData_ErrorInfo(this, search_code, search_time, start, limit);
        return return_data;
    }
    //清除故障记录
    public int DeleteSQLData_ErrorInfo()
    {
        WebUtil.DeleteSQLData_ErrorInfo(this);
        return 1;
    }

    //读取养锅配置列表
    public String GetSQLData_Bringup_List() {
        SaveLog("GetSQLData_Bringup_List()");

        try {
            //读取养锅配置
            String bring_config = dao.GetBringConfig();
            SaveLog("GetSQLData_Bringup_List--1111");
            JSONObject json_object = new JSONObject(bring_config);
            SaveLog("GetSQLData_Bringup_List--2222");
            JSONArray clean1_data = json_object.getJSONArray("clean1_data");
            SaveLog("GetSQLData_Bringup_List--3333");
            //JSONArray clean2_data = json_object.getJSONArray("clean2_data");
            //JSONArray clean3_data = json_object.getJSONArray("clean3_data");
            //JSONArray clean4_data = json_object.getJSONArray("clean4_data");
            String item1 = BringData_GetJson(clean1_data.getJSONObject(0), 1);
            SaveLog("GetSQLData_Bringup_List--4444");
            //String item2 = BringData_GetJson(clean2_data.getJSONObject(0), 2);
            //String item3 = BringData_GetJson(clean3_data.getJSONObject(0), 3);
            //String item4 = BringData_GetJson(clean4_data.getJSONObject(0), 4);
            //String return_json = "{\"success\":true,\"item_count\":4,\"item_data\":[" + item1 + "," + item2 + "," + item3 + "," + item4 + "]}";
            String return_json = "{\"success\":true,\"item_count\":4,\"item_data\":[" + item1 + "]}";
            return return_json;
        }
        catch (Exception ex)
        {
            SaveLog("GetSQLData_Bringup_List()出错：" + ex.getMessage());
        }

        return "{\"success\":false,\"item_count\":0,\"item_data\":[]}";
    }

    //自动养锅
    //type 洗锅方式：1快速养锅
    public boolean Bringup_Start(int type) {
        SaveLog("Bringup_Start("+type+")");
        //TTS_Speak("开始洗锅");

        try {
            //读取养锅配置
            String bring_config = dao.GetBringConfig();
            JSONObject json_object = new JSONObject(bring_config);
            JSONArray clean_data = json_object.getJSONArray("clean1_data");
            if (type == 2) clean_data = json_object.getJSONArray("clean2_data");
            if (type == 3) clean_data = json_object.getJSONArray("clean3_data");
            if (type == 4) clean_data = json_object.getJSONArray("clean4_data");
            if (clean_data == null) {
                SaveLog("Bringup_Start("+type+")参数不正确");
                return false;
            }
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle1_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle2_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle3_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle4_value", 0);
            //clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle5_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle6_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle7_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle8_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle9_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle10_value", 0);
            clean_data.getJSONObject(0).getJSONArray("steep_data").getJSONObject(1).put("nozzle11_value", 0);

            //创建自动养锅任务
            jobmaster = new CookingMaster(this, clean_data.getJSONObject(0), 3);
            return true;
        }
        catch (Exception ex)
        {
            SaveLog("Bringup_Start("+type+")出错：" + ex.getMessage());
        }
        return false;
    }

    //终止养锅
    public void Bringup_Stop() {
        try {
            //清空被计算的变量
            setting3position_name = "";
            setting_box_index = 0;
            setting_box_time = 0;
            setting_box_release_type = 0;
            if (setting3position_list != null)
                setting3position_list.clear();
            //停止
            jobmaster.Stop();
        }
        catch (Exception ex)
        {
            SaveLog("Bringup_Start()出错：" + ex.getMessage());
        }
    }

    //炒菜爪手动寻位—停止
    public void Device_SendCommand_Gripper_Stop(){
        SaveLog("Device_SendCommand_Gripper_Stop()");
        try {
            com.writeSingleRegister(0x01, 0x00EA, 0x5A00, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_Gripper_Stop()出错：" + ex.getMessage());
        }
    }
    //炒菜爪手动寻位—低速
    public void Device_SendCommand_Gripper_Slow(){
        SaveLog("Device_SendCommand_Gripper_Slow()");
        try {
            com.writeSingleRegister(0x01, 0x00EA, 0x5A01, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_Gripper_Slow()出错：" + ex.getMessage());
        }
    }
    //炒菜爪手动寻位—确认寻位
    public void Device_SendCommand_Gripper_OK(){
        SaveLog("Device_SendCommand_Gripper_OK()");
        try {
            com.writeSingleRegister(0x01, 0x00EA, 0x5A02, null);
        } catch (Exception ex) {
            SaveLog("Device_SendCommand_Gripper_OK()出错：" + ex.getMessage());
        }
    }


    public void sendBroadcast(String action) {
        Intent intent = new Intent(action);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }

}
